查找每两个处理指令之间的所有 XML 节点 [英] Finding all XML nodes between each two processing instructions
问题描述
使用 XPath
或 XSLT 1.0,我需要找到处理指令 和
之间的每个节点.代码>.代码如下:
Using XPath
or XSLT 1.0, I need to find each node between processing instructions <?start?>
and <?end?>
. The following code:
//node()[preceding-sibling::processing-instruction()[self::processing-instruction('start')]
following-sibling::processing-instruction()[ self::processing-instruction('end')]]`,
工作,但自然地,它只选择第一个 PI 和最后一个 PI 之间的节点.有没有办法只选择每个开始 - 结束对之间的节点?
works, but naturally, it only selects nodes between the first PI and the last PI. Is there any way how to select only the nodes that are between each start - end pair?
<root>
abc
<?start?>def<Highlighted
bold="yes"><Highlighted italic="yes">ghi</Highlighted></Highlighted>jkl
<?pi?>
<table>
<Caption>stu</Caption>
</table>vw
<?end?>
xy<?start?>
abc <Caption>def</Caption> ghi<?end?> jkl
</root>
推荐答案
这是一个 XSLT 2.0 示例,它使用 for-each-group group-starting-with/group-ending-with
来查找并输出这些处理指令对之间的节点:
Here is an XSLT 2.0 example that uses for-each-group group-starting-with/group-ending-with
to find and output the nodes between those pairs of processing instructions:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="root">
<xsl:for-each-group select="node()" group-starting-with="processing-instruction('start')">
<xsl:if test="self::processing-instruction('start')">
<group>
<xsl:for-each-group select="current-group() except ." group-ending-with="processing-instruction('end')">
<xsl:sequence select="current-group()[position() ne last()]"/>
</xsl:for-each-group>
</group>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
样品的结果是
<group>def<Highlighted bold="yes">
<Highlighted italic="yes">ghi</Highlighted>
</Highlighted>jkl
<?pi?>
<table>
<Caption>stu</Caption>
</table>vw
</group>
<group>
abc <Caption>def</Caption> ghi</group>
使用 XSLT 1.0,您可以计算 start
pi 之后和 end
pi 之前的节点的交集:
Using XSLT 1.0 you can compute the intersection of nodes following the start
pi and preceding the end
pi:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="start" match="root/node()[not(self::processing-instruction('start'))]" use="generate-id(preceding-sibling::processing-instruction('start')[1])"/>
<xsl:key name="end" match="root/node()[not(self::processing-instruction('end'))]" use="generate-id(following-sibling::processing-instruction('end')[1])"/>
<xsl:template match="root">
<xsl:apply-templates select="processing-instruction('start')"/>
</xsl:template>
<xsl:template match="processing-instruction('start')">
<xsl:variable name="end" select="following-sibling::processing-instruction('end')[1]"/>
<xsl:variable name="following-start" select="key('start', generate-id())"/>
<xsl:variable name="preceding-end" select="key('end', generate-id($end))"/>
<xsl:variable name="intersect" select="$following-start[count(. | $preceding-end) = count($preceding-end)]"/>
<group>
<xsl:copy-of select="$intersect"/>
</group>
</xsl:template>
</xsl:stylesheet>
这篇关于查找每两个处理指令之间的所有 XML 节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!