使用XSLT从平面XML数据创建嵌套XML元素输出

时间:2016-11-08 16:42:33

标签: xml xslt xml-parsing

我无法从平面XML数据源创建嵌套XML元素。我们的目标是采用<Path>,其中每个级别都通过列出每个<Level>在层次结构中表示,并将其转换为嵌套 <Folder>层次结构输出XML文件。

源数据集XML文件如下所示:

<Path>
  <Level DataID='2000' Name='Root'></Level>
  <Level DataID='427438' Name=Sub Level 1'></Level>
  <Level DataID='427439' Name=Sub Level 2'></Level>
  <Level DataID='427440' Name=Sub Level 3'></Level>
</Path>

所需的输出是嵌套的<folder>元素,其中嵌套元素的数量可能会因数据集中<levels>的数量而异。

<Parent>
<folder displayName="Root">
  <folder displayName="Level 1">
    <folder displayName="Level 2">
      <folder displayName="Level 3">
      </folder>
    </folder>
  </folder>
</folder>
</Parent>

我一直在尝试使用<xsl:apply-templates><xsl:for-each>标记的各种方法,其中输出使用<xsl:element>标记,但无济于事。

1 个答案:

答案 0 :(得分:0)

从平面输入创建嵌套结构的一种可能性如下所示。不幸的是,您的输入XML无效(请参阅上面的评论),因此输出不一定符合您的完整要求(“级别”前面有一个“Sub”):

这个XSLT应该通过递归应用xsl:call-template

来实现
<?xml version = "1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
    <xsl:template match="Path">
      <Parent>
        <xsl:call-template name="SubFolder">
          <xsl:with-param name="curElem" select="Level[1]" />
        </xsl:call-template>
      </Parent>
    </xsl:template>

    <xsl:template name="SubFolder">
      <xsl:param name="curElem" />
      <folder displayName="{$curElem/@Name}">
        <xsl:if test="$curElem/following-sibling::Level[1]">
          <xsl:call-template name="SubFolder">
            <xsl:with-param name="curElem" select="$curElem/following-sibling::Level[1]" />
          </xsl:call-template>
        </xsl:if>
      </folder>      
    </xsl:template>    
</xsl:stylesheet>

输出(应用于已清理的输入XML)如下所示:

<?xml version="1.0"?>
<Parent>
    <folder displayName="Root">
        <folder displayName="Sub Level 1">
            <folder displayName="Sub Level 2">
                <folder displayName="Sub Level 3"/>
            </folder>
        </folder>
    </folder>
</Parent>

可能有更简单的解决方案,但它可以胜任。