Reputation: 420
I am trying to transform XML with tree structure into a flat list. This is a small part of input XML that I am trying to transform:
<category_list>
<category>
<id>12</id>
<name>Forks</name>
<sub_categories>
<category>
<id>15</id>
<name>26"</name>
<sub_categories />
</category>
<category>
<id>16</id>
<name>27,5"</name>
<sub_categories />
</category>
<category>
<id>19</id>
<name>27,5+"</name>
<sub_categories />
</category>
<category>
<id>17</id>
<name>29"</name>
<sub_categories />
</category>
</sub_categories>
</category>
<category>
<id>13</id>
<name>Shocks</name>
<sub_categories />
</category>
<category>
<id>14</id>
<name>Springs</name>
<sub_categories />
</category>
</category_list>
I need output like this:
<categories>
<category>
<id>12</id>
<name>Forks</name>
<parent_category>0</parent_category>
<order_by>1</order_by>
</category>
<category>
<id>15</id>
<name>26"</name>
<parent_category>12</parent_category>
<order_by>1</order_by>
</category>
<category>
<id>16</id>
<name>27,5"</name>
<parent_category>12</parent_category>
<order_by>2</order_by>
</category>
<category>
<id>19</id>
<name>27,5+"</name>
<parent_category>12</parent_category>
<order_by>3</order_by>
</category>
<category>
<id>17</id>
<name>29"</name>
<parent_category>12</parent_category>
<order_by>4</order_by>
</category>
<category>
<id>13</id>
<name>Shocks</name>
<parent_category>0</parent_category>
<order_by>2</order_by>
</category>
<category>
<id>14</id>
<name>Springs</name>
<parent_category>0</parent_category>
<order_by>3</order_by>
</category>
</categories>
I have no idea how to do it. First problem is to change tree structure to flat list and second problem is add an order_by tag that increments with category count.
Can you please advice?
Upvotes: 0
Views: 276
Reputation: 167716
You can process all //category
and then use position()
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="category_list">
<categories>
<xsl:apply-templates select="//category"/>
</categories>
</xsl:template>
<xsl:template match="category">
<xsl:copy>
<xsl:copy-of select="*[not(self::sub_categories)]"/>
<parent_category>
<xsl:choose>
<xsl:when test="../parent::category">
<xsl:value-of select="../parent::category/id"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</parent_category>
<order_by>
<xsl:value-of select="position()"/>
</order_by>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1