我的XML非常扁平,这是一个例子:
<?xml version="1.0" encoding="UTF-8"?>
<Elements>
<Header>
<Divison>A</Divison>
<ParentNumber>2016041330</ParentNumber>
</Header>
<Header>
<Divison>C</Divison>
<ParentNumber>2016041323</ParentNumber>
</Header>
<Element>
<Number>2016041312</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>8</Risk>
</Element>
<Element>
<Number>2016041342</Number>
<ParentNumber>2016041323</ParentNumber>
<Risk>2</Risk>
</Element>
<Element>
<Number>2016041318</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>0</Risk>
</Element>
<Element>
<Number>2016041330</Number>
<ParentNumber>2016041323</ParentNumber>
<Risk>7</Risk>
</Element>
</Elements>
它们需要以这样的方式嵌套:
<?xml version="1.0" encoding="UTF-8"?>
<Elements>
<Header>
<Divison>C</Divison>
<ParentNumber>2016041323</ParentNumber>
<Element>
<Number>2016041342</Number>
<ParentNumber>2016041323</ParentNumber>
<Risk>2</Risk>
</Element>
<Header>
<Divison>A</Divison>
<ParentNumber>2016041330</ParentNumber>
<Risk>7</Risk>
<Element>
<Number>2016041312</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>8</Risk>
</Element>
<Element>
<Number>2016041318</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>0</Risk>
</Element>
</Header>
</Header>
</Elements>
我尝试了以下转换:
(特别感谢michael.hor257k)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="child-by-parent" match="Header | Element" use="ParentNumber" />
<xsl:key name="parent" match="Header | Element" use="Number" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Elements">
<xsl:copy>
<xsl:apply-templates select="*[not(key('parent', ParentNumber))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Header | Element">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="key('child-by-parent', Number)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
具有以下结果:
<?xml version="1.0" encoding="UTF-8"?>
<Elements>
<Header>
<Divison>C</Divison>
<ParentNumber>2016041323</ParentNumber>
</Header>
<Element>
<Number>2016041342</Number>
<ParentNumber>2016041323</ParentNumber>
<Risk>2</Risk>
</Element>
<Element>
<Number>2016041330</Number>
<ParentNumber>2016041323</ParentNumber>
<Risk>7</Risk>
<Header>
<Divison>A</Divison>
<ParentNumber>2016041330</ParentNumber>
</Header>
<Element>
<Number>2016041312</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>8</Risk>
</Element>
<Element>
<Number>2016041318</Number>
<ParentNumber>2016041330</ParentNumber>
<Risk>0</Risk>
</Element>
</Element>
</Elements>
[element]标签包含两种信息:number和parentnumber。数字是[元素]的不同数字。 parentnumber引用另一个[element]。数字和父数字都对应于[标题],然后[元素]用作链接并且可以解散。但是,如果只有父编号与[header]相对应,则将[element]标记分配给[header]标记。
答案 0 :(得分:1)
我不明白你获得结果的逻辑。 AFAICS,您有三个没有父节点的元素:
<Header>
<Divison>C</Divison>
<ParentNumber>2016041323</ParentNumber>
</Header>
<Element>
<Number>2016041342</Number>
<ParentNumber>2016041323</ParentNumber>
</Element>
<Element>
<Number>2016041330</Number>
<ParentNumber>2016041323</ParentNumber>
</Element>
所以我希望这些是兄弟姐妹在层次结构的顶层。然后你会让这三个分支中的每一个递归地嵌套它们的后代 - 获得:
<Elements>
<Header>
<Divison>C</Divison>
<ParentNumber>2016041323</ParentNumber>
</Header>
<Element>
<Number>2016041342</Number>
<ParentNumber>2016041323</ParentNumber>
</Element>
<Element>
<Number>2016041330</Number>
<ParentNumber>2016041323</ParentNumber>
<Header>
<Divison>A</Divison>
<ParentNumber>2016041330</ParentNumber>
</Header>
<Element>
<Number>2016041312</Number>
<ParentNumber>2016041330</ParentNumber>
</Element>
<Element>
<Number>2016041318</Number>
<ParentNumber>2016041330</ParentNumber>
</Element>
</Element>
</Elements>
这可以通过以下方式实现:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="child-by-parent" match="Header | Element" use="ParentNumber" />
<xsl:key name="parent" match="Header | Element" use="Number" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Elements">
<xsl:copy>
<xsl:apply-templates select="*[not(key('parent', ParentNumber))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Header | Element">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="key('child-by-parent', Number)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>