如何将平面xml数组转换为树?

时间:2013-02-08 19:54:54

标签: xml xslt-1.0

有人可以帮助以下吗?

我需要转换

<categories type="array">
      <category type="array">
        <category-name><![CDATA[Categories]]></category-name>
        <category-name><![CDATA[BAGS & TRIPODS]]></category-name>
        <category-name><![CDATA[Bags & Cases]]></category-name>
        <category-name><![CDATA[soft cases]]></category-name>
        <category-name><![CDATA[camera]]></category-name>
      </category>
    </categories>

<Category>
        <Name>BAGS &amp; TRIPODS</Name>
        <Category>
          <Name>Bags &amp; Cases</Name>
          <Category>
            <Name>soft cases</Name>
            <Category>
              <Name>camera</Name>
            </Category>
          </Category>
        </Category>
      </Category>

这必须在XSLT 1.0中。谢谢!

1 个答案:

答案 0 :(得分:3)

你的意思是你想把一个平坦的序列变成一棵树,其中每个父母只有一个孩子?

在父元素的模板中,不要将模板应用于所有子项,而应仅应用于第一个子项:

  <xsl:template match="category[@type='array']">
    <xsl:apply-templates select="*[1]"/>    
  </xsl:template>

然后在每个子项的模板中,通过写出一个新的Category元素及其Name来处理该子项,然后将模板应用于紧随其后的兄弟:

  <xsl:template match="category-name">
    <Category>
      <Name>
        <xsl:apply-templates/>
      </Name>
      <xsl:apply-templates select="following-sibling::*[1]"/>
    </Category>
  </xsl:template>

在您的示例中,数组中的初始项似乎被删除;我们需要特殊代码:

  <xsl:template match="category-name
                       [normalize-space = 'Categories']">
    <xsl:apply-templates select="following-sibling::*[1]"/>
  </xsl:template>  

所有在一起:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

   <xsl:output method="xml" indent="yes"/>

  <xsl:template match="category[@type='array']">
    <xsl:apply-templates select="*[1]"/>    
  </xsl:template>

  <xsl:template match="category-name[normalize-space = 'Categories']">
    <xsl:apply-templates select="following-sibling::*[1]"/>
  </xsl:template>  

  <xsl:template match="category-name">
    <Category>
      <Name>
        <xsl:apply-templates/>
      </Name>
      <xsl:apply-templates select="following-sibling::*[1]"/>
    </Category>
  </xsl:template>

</xsl:stylesheet>

根据您提供的输入,产生以下内容:

<Category>
  <Name>Categories</Name>
  <Category>
    <Name>BAGS &amp; TRIPODS</Name>
    <Category>
      <Name>Bags &amp; Cases</Name>
      <Category>
        <Name>soft cases</Name>
        <Category>
          <Name>camera</Name>
        </Category>
      </Category>
    </Category>
  </Category>
</Category>