xslt - How to merge multiple XML entries into one tree with XSL -


i have xml i'm trying restructure xsl. quite new xsl appreciated.

my current xml given me this.

<catalogitem>   <partnumber>114-0015</partnumber>   <itemname>this item 1</itemname>   <price>$5.69</price> </catalogitem> <catalogitem>   <partnumber>114-0016</partnumber>   <itemname>this sub-item1</itemname>   <price>$6.29</price>   <parent>114-0015</parent> </catalogitem> <catalogitem>   <partnumber>114-0017</partnumber>   <itemname>this sub-item2</itemname>   <price>$7.29</price>   <parent>114-0015</parent> </catalogitem> <catalogitem>   <partnumber>114-0018</partnumber>   <itemname>this sub-item3</itemname>   <price>$8.29</price>   <parent>114-0015</parent> </catalogitem> 

i'm wondering if possible restructure catalogitem parent tag inserted xml tree structure. note parent tag corresponds partnumber of items parent. final output be:

<catalogitem>   <partnumber>114-0015</partnumber>   <itemname>this item 1</itemname>   <price>$5.69</price>   <subitem>     <subpartnumber>114-0016</subpartnumber>     <subitemname>this sub-item1</subitemname>     <subprice>$6.29</subprice>   </subitem>   <subitem>     <subpartnumber>114-0017</subpartnumber>     <subitemname>this sub-item2</subitemname>     <subprice>$7.29</subprice>   </subitem>   <subitem>     <subpartnumber>114-0018</subpartnumber>     <subitemname>this sub-item3</subitemname>     <subprice>$8.29</subprice>   </subitem> </catalogitem> 

could please point me in right direction (hopefully provide code samples) me out. thanks!

edit: including current xslt i'm using other transformations.

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">   <xsl:template match="/"> <dataroot>   <xsl:for-each select="dataroot/catalogitem">     <catalogitem>     <xsl:if test="not(partnumber)"><intro>       <xsl:if test="not(partnumber)"><itemnameintro><xsl:value-of select="itemname"/></itemnameintro></xsl:if>       <xsl:if test="not(partnumber)"><longdescriptionintro><xsl:value-of select="longdescription"/></longdescriptionintro></xsl:if>       </intro></xsl:if>       <xsl:copy-of select="photo1"/>       <xsl:copy-of select="categorytype"/>       <xsl:copy-of select="bookseries"/>       <xsl:copy-of select="photo2"/>       <xsl:copy-of select="photo3"/>       <xsl:copy-of select="photo4"/>       <xsl:copy-of select="logo"/>       <xsl:if test="partnumber"><itemname><xsl:value-of select="itemname"/></itemname></xsl:if>       <xsl:copy-of select="author"/>       <xsl:if test="partnumber"><longdescription><xsl:value-of select="longdescription"/></longdescription></xsl:if>       <xsl:if test="size1">         <size1><xsl:value-of select="size1"/><xsl:if test="size1 , size2"> | </xsl:if></size1>       </xsl:if>       <xsl:copy-of select="size2"/>       <xsl:if test="age">         <age><xsl:if test="size1 , age or size2 , age"> | </xsl:if>age: <xsl:value-of select="age"/></age>       </xsl:if>       <xsl:if test="numberpages">         <numberpages><xsl:value-of select="numberpages"/>p </numberpages>       </xsl:if>       <xsl:copy-of select="partnumber"/>       <xsl:if test="price">         <pricetab>  $</pricetab>       </xsl:if>       <xsl:if test="price">         <price><xsl:value-of select="price"/></price>       </xsl:if>     </catalogitem>   </xsl:for-each> </dataroot> 

your "current xml" not xml @ all, has no single root element.

given well-formed xml input such as:

<catalog>   <catalogitem>     <partnumber>114-0015</partnumber>     <itemname>this item 1</itemname>     <price>$5.69</price>   </catalogitem>   <catalogitem>     <partnumber>114-0016</partnumber>     <itemname>this sub-item1</itemname>     <price>$6.29</price>     <parent>114-0015</parent>   </catalogitem>   <catalogitem>     <partnumber>114-0017</partnumber>     <itemname>this sub-item2</itemname>     <price>$7.29</price>     <parent>114-0015</parent>   </catalogitem>   <catalogitem>     <partnumber>114-0018</partnumber>     <itemname>this sub-item3</itemname>     <price>$8.29</price>     <parent>114-0015</parent>   </catalogitem> </catalog> 

the following stylesheet:

xslt 1.0

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/>  <xsl:key name="child" match="catalogitem" use="parent" />  <!-- identity transform --> <xsl:template match="@*|node()">     <xsl:copy>         <xsl:apply-templates select="@*|node()"/>     </xsl:copy> </xsl:template>  <xsl:template match="/catalog">     <xsl:copy>         <xsl:apply-templates select="catalogitem[not(parent)]"/>     </xsl:copy> </xsl:template>  <xsl:template match="catalogitem">     <xsl:copy>         <xsl:apply-templates/>         <xsl:apply-templates select="key('child', partnumber)" mode="sub"/>     </xsl:copy> </xsl:template>  <xsl:template match="catalogitem" mode="sub">     <subitem>     <subpartnumber>         <xsl:value-of select="partnumber"/>     </subpartnumber>     <subitemname>         <xsl:value-of select="itemname"/>        </subitemname>     <subprice>         <xsl:value-of select="price"/>       </subprice>     </subitem> </xsl:template>  </xsl:stylesheet> 

will return:

<?xml version="1.0" encoding="utf-8"?> <catalog>    <catalogitem>       <partnumber>114-0015</partnumber>       <itemname>this item 1</itemname>       <price>$5.69</price>       <subitem>          <subpartnumber>114-0016</subpartnumber>          <subitemname>this sub-item1</subitemname>          <subprice>$6.29</subprice>       </subitem>       <subitem>          <subpartnumber>114-0017</subpartnumber>          <subitemname>this sub-item2</subitemname>          <subprice>$7.29</subprice>       </subitem>       <subitem>          <subpartnumber>114-0018</subpartnumber>          <subitemname>this sub-item3</subitemname>          <subprice>$8.29</subprice>       </subitem>    </catalogitem> </catalog> 

Comments