本文介绍了嵌套平面 XML 兄弟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
尝试使用 XSLT 2.0 转换 XML.
Attemping to transform XML with XSLT 2.0.
平面源 XML:
<body>
<R1/>
<R1/>
<R2/>
<R2/>
<R2/>
<R3/>
<R3/>
<R3/>
<R1/>
<R1/>
<R2/>
<R2/>
<R1/>
</body>
期望的输出:
<body>
<R1/>
<R1>
<R2/>
<R2/>
<R2>
<R3/>
<R3/>
<R3/>
</R2>
</R1>
<R1/>
<R1>
<R2/>
<R2/>
</R1>
<R1/>
</body>
基本上这些 R1 - R3 元素表示 sect-1、sect-2、sect-3 类型的元素.R2 嵌套在其先前的兄弟 R1 中,而 R3 嵌套在其先前的兄弟 R2 中.相同的元素处于同一级别.
Basically these R1 - R3 elements signify sect-1, sect-2, sect-3 type elements. R2's are nested within their previous sibling R1 and R3's are nested within their previous sibling R2. Elements that are the same are on the same level.
推荐答案
Use for-each-group group-starting-with:
Use for-each-group group-starting-with:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:param name="prefix" as="xs:string" select="'R'"/>
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element()*">
<xsl:param name="elements" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="*[local-name() = concat($prefix, $level)]">
<xsl:element name="{name()}">
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:element>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="body">
<xsl:copy>
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这篇关于嵌套平面 XML 兄弟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!