2016-04-15 81 views
0

我试图将带有树形结构的XML转换为平面列表。这是输入XML的一小部分,我想变换:使用XSLT将具有树形数据结构的XML转换为平面结构

<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> 

我需要的输出是这样的:

<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> 

我不知道该怎么做。第一个问题是将树结构更改为平面列表,第二个问题是添加一个order_by标签,该标签会随类别数量递增。

你能请指教吗?

回答

1

可以处理所有//category然后用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> 
+0

这是工作,但有一个问题。父类别始终是列表中第一个类别的标识。如果类别Shocks在Forks之前,那么Forks的所有子类别都具有parent_category = 13而不是12. – sajushko

+0

因此,看起来我知道了。我用条件ancestor :: category而不是../../category和ancestor :: category/id in value-of。看起来它现在工作,我需要。 Thx很多帮助马丁。 – sajushko

+0

@sajushko,对于这个问题感到抱歉,我的XPath出错了,现在已经修复了,尽管你自己也找到了修复方法。 –