我想不出一个简单的表达方式,我想知道下面使用
path
和 xsl:evaluate
的代码是否实现了要求:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
xmlns:mf="http://example.com/mf"
expand-text="yes">
<xsl:function name="mf:cousins" as="node()*">
<xsl:param name="node" as="node()"/>
<xsl:variable name="path" select="path($node)"/>
<xsl:variable name="path-without-predicates" select="replace($path, '\[[0-9]+\]', '')"/>
<xsl:variable name="cousins" as="node()*">
<xsl:evaluate context-item="$node" xpath="$path-without-predicates"/>
</xsl:variable>
<xsl:sequence select="$cousins except $node"/>
</xsl:function>
<xsl:function name="mf:preceding-cousins" as="node()*">
<xsl:param name="node" as="node()"/>
<xsl:sequence select="mf:cousins($node)[. << $node]"/>
</xsl:function>
<xsl:template match="level2[@id = 6] | level2[@id = 5]">
<xsl:comment>preceding cousin: {mf:preceding-cousins(.)[last()]=>serialize(map{ 'method' : 'xml' })}</xsl:comment>
<xsl:next-match/>
</xsl:template>
<xsl:output method="xml" indent="no"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
使用
path
函数,然后进行字符串替换和 xsl:evaluate
看起来有点像“黑客”,但我没有看到简单、直接的 XPath。