RE: [xsl] Assembling nodes from parts outside of the current node

Subject: RE: [xsl] Assembling nodes from parts outside of the current node
From: "Scott Trenda" <Scott.Trenda@xxxxxxxx>
Date: Thu, 25 Oct 2007 12:42:58 -0500
Whoops - I put @id in the key() function, instead of @partId. New source
is below. Also, since you probably won't want <id>part03</id> to show up
in the <part> section, I altered that too. Try this one:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:key name="parts" match="allParts/part" use="@id"/>

  <xsl:template match="insects|insect|insect/name">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="partMaps">
    <parts>
      <xsl:apply-templates/>
    </parts>
  </xsl:template>

  <xsl:template match="partMap">
    <part>
      <xsl:apply-templates select="key('parts', @partId)/@*"/>
    </part>
  </xsl:template>

  <xsl:template match="allParts/part/@*[not(name() = 'id')]">
    <xsl:element name="{name()}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>


~ Scott


-----Original Message-----
From: Mark Peters [mailto:flickrmeister@xxxxxxxxx]
Sent: Thursday, October 25, 2007 11:43 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Assembling nodes from parts outside of the current
node

Hi Scott,

Thanks for the help!

I applied your transformation to the original document, but the output
doesn't include the part data. Any idea why?

<?xml version="1.0" encoding="UTF-8"?>
		<insects>
			<insect>
				<name>Bee</name>
				<parts>
					<part/>
					<part/>
				</parts>
			</insect>
			<insect>
				<name>Caterpillar</name>
				<parts>
					<part/>
				</parts>
			</insect>
			<insect>
				<name>Butterfly</name>
				<parts>
					<part/>
					<part/>
				</parts>
			</insect>
		</insects>

Thanks,
Mark


On 10/25/07, Scott Trenda <Scott.Trenda@xxxxxxxx> wrote:
> Keys are your friends! :)
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
>   <xsl:key name="parts" match="allParts/part" use="@id"/>
>
>   <xsl:template match="insects|insect|insect/name">
>     <xsl:copy>
>       <xsl:apply-templates/>
>     </xsl:copy>
>   </xsl:template>
>
>   <xsl:template match="partMaps">
>     <parts>
>       <xsl:apply-templates/>
>     </parts>
>   </xsl:template>
>
>   <xsl:template match="partMap">
>     <part>
>       <xsl:apply-templates select="key('parts', @id)/@*"/>
>     </part>
>   </xsl:template>
>
>   <xsl:template match="allParts/part/@*">
>     <xsl:element name="{name()}">
>       <xsl:value-of select="."/>
>     </xsl:element>
>   </xsl:template>
>
> </xsl:stylesheet>
>
> ~ Scott
>
>
> -----Original Message-----
> From: Mark Peters [mailto:flickrmeister@xxxxxxxxx]
> Sent: Thursday, October 25, 2007 11:02 AM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Assembling nodes from parts outside of the current node
>
> Hi Everyone,
>
> This one has me stumped. I have a collection of nodes that store the
> names of insects and include sub-nodes that map to the parts of
> insects, stored elsewhere in the document.
>
> <?xml version=" 1.0" encoding="UTF-8"?>
> <kingdoms>
>     <kingdom>
>         <insects>
>             <insect>
>                 <name>Bee</name>
>                 <partMaps>
>                     <partMap mapId="pmap01" partId="part01"/>
>                     <partMap mapId="pmap01" partId="part02"/>
>                 </partMaps>
>              </insect>
>             <insect>
>                 <name>Caterpillar</name>
>                 <partMaps>
>                     <partMap mapId="pmap02" partId="part01"/>
>                 </partMaps>
>             </insect>
>             <insect>
>                 <name>Butterfly</name>
>                 <partMaps>
>                     <partMap mapId="pmap03" partId="part01"/>
>                     <partMap mapId="pmap01" partId="part02"/>
>                 </partMaps>
>             </insect>
>         </insects>
>         <allParts>
>             <part id="part01" name="legs" description="Walks with
> these"/>
>             <part id="part02" name="wings" description="Flies with
> these"/>
>         </allParts>
>     </kingdom>
> </kingdoms>
>
>
> What I'm trying to do is list each insect and its parts in a series of
> nodes, as follows. For each insect, I only want to display the parts
> that pertain to that insect.
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <insects>
>     <insect>
>         <name>Bee</name>
>         <parts>
>             <part>
>                 <name>Legs</name>
>                 <description>Walks with these</description>
>             </part>
>             <part>
>                 <name>Wings</name>
>                 <description>Flies with these</description>
>             </part>
>         </parts>
>     </insect>
>     <insect>
>         <name>Caterpillar</name>
>         <parts>
>             <part>
>                 <name>Legs</name>
>                 <description>Walks with these</description>
>             </part>
>         </parts>
>     </insect>
>     <insect>
>         <name>Butterfly</name>
>         <parts>
>             <part>
>                 <name>Legs</name>
>                 <description>Walks with these</description>
>             </part>
>             <part>
>                 <name>Wings</name>
>                 <description>Flies with these</description>
>             </part>
>         </parts>
>     </insect>
> </insects>
>
>
> I thought I'd simply need to compare the partMap/@partId values with
> the corresponding part/@id values, as follows. The output currently
> displays the insects, but not their parts. (We could argue that if
> there are no parts, there are no objects. But that's another
> discussion. :-)
>
>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0">
>     <xsl:output method="xml" version=" 1.0"/>
>     <xsl:template match="/">
>         <insects>
>             <xsl:for-each select="kingdoms/kingdom
> /insects/insect">
>                 <xsl:sort select="name"/>
>                 <insect>
>                     <name>
>                         <xsl:value-of select="name"/>
>                     </name>
>                     <xsl:for-each select="partMaps/partMap">
>                         <xsl:choose>
>                             <xsl:when
> test="@partId=:../../../allParts/part/@id">
>                                 <part>
>                                     <name>
>                                         <xsl:value-of
> select=":../../../allParts/part/@name"/>
>                                     </name>
>                                     <description>
>                                         <xsl:value-of
> select=":../../../allParts/part/@description"/>
>                                     </description>
>                                 </part>
>                             </xsl:when>
>                             <xsl:otherwise/>
>                         </xsl:choose>
>                     </xsl:for-each>
>                 </insect>
>             </xsl:for-each>
>         </insects>
>     </xsl:template>
> </xsl:stylesheet>
>
>
> By the way, I'm not an entomologist. Insects probably don't belong
> directly within kingdoms. They're probably a genus or species or
> something. :-)  This is just test data.
>
> Thanks in advance for any help you could offer.
>
> Mark
>
> --
>
> Mark Peters
> Senior Technical Writer
> Saba Software
>
>


--

Mark Peters
Senior Technical Writer
Saba Software

Current Thread