Xslt 如何将Xml转换为分层Xml
我有这个XML文件,希望执行XSLT2.0转换 问题是,这些节点处于同一级别,并使用ID相互引用,例如:Xslt 如何将Xml转换为分层Xml,xslt,xslt-2.0,Xslt,Xslt 2.0,我有这个XML文件,希望执行XSLT2.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" r
<?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>
文本1
文本2
文本3
文本4
文本5
所需的输出应如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Level1>
Text1
<Level2>
Text2
<Level3>
Text4
</Level3>
</Level2>
<Level2>
Text3
<Level3>
Text5
</Level3>
</Level2>
</Level1>
文本1
文本2
文本4
文本3
文本5
我已经尝试使用模板并递归调用它们,但没有成功。
也许有一个简单的方法来解决这类问题。
提前感谢您的帮助 您可以使用键通过
id
属性标识数据
元素,然后使用标记(@referenceID,'\s+')上的key
函数遵循引用:
<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>
这就提供了正确的结构,很难识别混合内容。是否应该为数据元素提供一个公共容器元素?是什么决定了哪些元素构成了嵌套输出的第一级,这仅仅是顺序,还是您需要检查哪些元素没有被其他元素引用?谢谢您的输入!对不起,描述不准确。我已经给出,顶级ID是“1”,所有引用的ID都是这个ID的子级。因此必须遵循所有参考ID。数据元素有一个通用的容器,但我看不出这个容器如何帮助我进行转换。谢谢你的帮助!如果起始ID不是“1”或类似字符串“id2”的起始ID,这种方法是否也有效?例如,如果ID的引用类似于“id2”引用“id5”和“id5”引用“id11”,则该键与输入XML中用作ID
属性的任何值一起工作。当然,您需要更改
以使用您拥有的任何值,例如
。如果需要将其作为参数,可以声明一个全局(顶级)
,然后将行更改为
。然后,在运行转换时可以设置全局参数(例如,从命令行或使用API或IDE)。谢谢Martin!我将您的建议用于全局变量,并且能够实现所需的输出!缩进通过使用:
和