如何将Xml转换为分层Xml

时间:2018-01-21 14:32:44

标签: xslt xslt-2.0

我有这个XML文件,想要执行Xslt 2.0转换。

问题是,节点处于同一级别并且使用ID来引用彼此,例如:

<?xml version="1.0" encoding="UTF-8"?>

<Data id = "1" referenceID = "2 3">
    Text1
</Data>

<Data id = "2" referenceID = "4">
    Text2
</Data>

<Data id = "3" referenceID = "5">
    Text3
</Data>

<Data id = "4">
    Text4
</Data>

<Data id = "5">
    Text5
</Data>

所需的输出应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Level1>
    Text1
    <Level2>
        Text2
        <Level3>
            Text4
        </Level3>
    </Level2>

    <Level2>
        Text3
        <Level3>
            Text5
        </Level3>
    </Level2>
</Level1>

我已经尝试过使用模板并递归调用它们但没有成功。 也许有一种简单的方法可以解决这类问题。 感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您可以使用密钥通过Data属性识别id元素,然后使用key序列上的tokenize(@referenceID, '\s+')函数关注参考:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

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

  <xsl:key name="ref" match="Data" use="@id"/>

  <xsl:template match="*[Data[@id]]">
      <xsl:apply-templates select="key('ref', '1')"/>
  </xsl:template>

  <xsl:template match="Data">
      <xsl:param name="level" as="xs:integer" select="1"/>
      <xsl:element name="Level{$level}">
          <xsl:apply-templates select="node(), key('ref', tokenize(@referenceID, '\s+'))">
              <xsl:with-param name="level" select="$level + 1"/>
          </xsl:apply-templates>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

这给出了正确的结构http://xsltfiddle.liberty-development.net/gWcDMek/2,难以识别混合内容。