我正在使用测试描述解析一个巨大的word文件,并且存在节点范围问题。 Word基本上创建了段落列表,我想将它们分组到父节点。因此,对于每个节点'A',我想将以下所有节点分组到下一个节点'A'到'A'。
如何使用XSL完成?
实施例: 我已经到了:
<A/>
<ab/>
<ac/>
<A/>
<ab/>
<ac/>
但需要:
<A>
<ab/>
<ac/>
</A>
<A>
<ab/>
<ac/>
</A>
谢谢!
答案 0 :(得分:4)
使用密钥有一个简单而强大的解决方案。
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kFollowing" match="*[not(self::A)]"
use="generate-id(preceding-sibling::A[1])"/>
<xsl:template match="/*">
<t>
<xsl:apply-templates select="A"/>
</t>
</xsl:template>
<xsl:template match="A">
<A>
<xsl:copy-of select=
"key('kFollowing',generate-id())"/>
</A>
</xsl:template>
</xsl:stylesheet>
应用于原始XML文档时:
<t>
<A/>
<ab/>
<ac/>
<A/>
<ab/>
<ac/>
</t>
产生想要的结果:
<t>
<A>
<ab/>
<ac/>
</A>
<A>
<ab/>
<ac/>
</A>
</t>
请注意 <xsl:key>
的定义如何与key()
函数的使用相结合,最简单自然地收集两个相邻{{1}之间的所有兄弟元素元素。
答案 1 :(得分:3)
如果您想匹配<A>
之后的所有节点,但是在下一个<A>
之前,我认为您可以使用以下内容:
<xsl:template match="A">
<xsl:copy>
<!-- start of range -->
<xsl:variable name="start" select="count(preceding-sibling::*) + 1" />
<!-- end of range -->
<xsl:variable name="stop">
<xsl:choose>
<!-- either just before the next A node -->
<xsl:when test="following-sibling::A">
<xsl:value-of select="count(following-sibling::A[1]/preceding-sibling::*) + 1" />
</xsl:when>
<!-- or all the rest -->
<xsl:otherwise>
<xsl:value-of select="count(../*) + 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- this for debugging only -->
<xsl:attribute name="range">
<xsl:value-of select="concat($start + 1, '-', $stop - 1)" />
</xsl:attribute>
<!-- copy all nodes in the calculated range -->
<xsl:for-each select="../*[position() > $start and position() < $stop]">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:copy>
</xsl:template>
您的意见:
<root>
<A />
<ab />
<ac />
<A />
<ab />
<ac />
</root>
我得到了(我保留了“范围”属性以使计算可见):
<A range="2-3">
<ab />
<ac />
</A>
<A range="5-6">
<ab />
<ac />
</A>
答案 2 :(得分:3)
XSLT 2.0解决方案:
<xsl:for-each-group select="*" group-starting-with="A">
<xsl:element name="{name(current-group()[1])}">
<xsl:copy-of select="current-group()[position() gt 1]"/>
</xsl:element>
</xsl:for-each-group>