如何确定 XPath 中的嵌套级别?
How to determine the nesting level in XPath?
在下面的示例中,我想确定具有 XPath (2.0) 表达式的节点的 "nesting level"。这 "nesting level" 将是连续后代的数量,例如如果 "span/span/span" 存在,则为 3。预期的嵌套级别在注释中给出:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor. Aenean massa.
<span><!--nesting level:2-->Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<span><!--nesting levels:1-->Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
<span><!--nesting levels:0-->Nulla consequat massa quis enim.</span>
</span>
<span><!--nesting levels:0-->Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.</span>
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
</span>
<span><!--nesting levels:0-->Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus
elementum semper nisi.
</span>
<span><!--nesting levels:0-->Aenean vulputate eleifend tellus. Aenean leo ligula,
porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
quis, feugiat a, tellus.
</span>
</div>
<div>Phasellus viverra nulla ut metus varius laoreet.
<span><!--nesting levels:0-->Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
</span>
<span><!--nesting levels:2-->Curabitur ullamcorper ultricies nisi.
<span><!--nesting levels:0-->Nam eget dui.</span>
Etiam rhoncus.
<span><!--nesting levels:1-->Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet
adipiscing sem neque sed ipsum.
<span><!--nesting levels:0-->Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.</span>
<span><!--nesting levels:0-->Maecenas nec odio et ante tincidunt tempus.</span>
Donec vitae sapien ut libero venenatis faucibus.
<span><!--nesting levels:0-->Nullam quis ante.</span>
</span>
Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet
nibh.
</span>
Donec sodales sagittis magna.
</div>
</text>
现在,我尝试了 count(descendant::span))
,但显然,这也会包括所有兄弟姐妹,并且在许多情况下会产生错误的结果。我还尝试了 count(descendant::span[1]))
和 count(descendant::span[position() = 1]))
,它们也给出了错误的结果。我还不知道如何从总数中排除兄弟姐妹的数量。任何提示表示赞赏。
在 XSLT 中,我使用表达式
获得了正确的值
max(
for $leaf in descendant-or-self::span[not(span)]
return count($leaf/ancestor-or-self::span except ancestor-or-self::span)
)
例如使用样式表
<?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"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="span">
<xsl:copy>
<xsl:attribute name="nesting-level"
select="
max(
for $leaf in descendant-or-self::span[not(span)]
return count($leaf/ancestor-or-self::span except ancestor-or-self::span)
)"/>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我得到了输出
<?xml version="1.0" encoding="UTF-8"?><text>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor. Aenean massa.
<span nesting-level="2"><!--nesting level:2-->Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<span nesting-level="1"><!--nesting levels:1-->Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
<span nesting-level="0"><!--nesting levels:0-->Nulla consequat massa quis enim.</span>
</span>
<span nesting-level="0"><!--nesting levels:0-->Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.</span>
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
</span>
<span nesting-level="0"><!--nesting levels:0-->Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus
elementum semper nisi.
</span>
<span nesting-level="0"><!--nesting levels:0-->Aenean vulputate eleifend tellus. Aenean leo ligula,
porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
quis, feugiat a, tellus.
</span>
</div>
<div>Phasellus viverra nulla ut metus varius laoreet.
<span nesting-level="0"><!--nesting levels:0-->Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
</span>
<span nesting-level="2"><!--nesting levels:2-->Curabitur ullamcorper ultricies nisi.
<span nesting-level="0"><!--nesting levels:0-->Nam eget dui.</span>
Etiam rhoncus.
<span nesting-level="1"><!--nesting levels:1-->Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet
adipiscing sem neque sed ipsum.
<span nesting-level="0"><!--nesting levels:0-->Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.</span>
<span nesting-level="0"><!--nesting levels:0-->Maecenas nec odio et ante tincidunt tempus.</span>
Donec vitae sapien ut libero venenatis faucibus.
<span nesting-level="0"><!--nesting levels:0-->Nullam quis ante.</span>
</span>
Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet
nibh.
</span>
Donec sodales sagittis magna.
</div>
</text>
在下面的示例中,我想确定具有 XPath (2.0) 表达式的节点的 "nesting level"。这 "nesting level" 将是连续后代的数量,例如如果 "span/span/span" 存在,则为 3。预期的嵌套级别在注释中给出:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor. Aenean massa.
<span><!--nesting level:2-->Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<span><!--nesting levels:1-->Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
<span><!--nesting levels:0-->Nulla consequat massa quis enim.</span>
</span>
<span><!--nesting levels:0-->Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.</span>
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
</span>
<span><!--nesting levels:0-->Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus
elementum semper nisi.
</span>
<span><!--nesting levels:0-->Aenean vulputate eleifend tellus. Aenean leo ligula,
porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
quis, feugiat a, tellus.
</span>
</div>
<div>Phasellus viverra nulla ut metus varius laoreet.
<span><!--nesting levels:0-->Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
</span>
<span><!--nesting levels:2-->Curabitur ullamcorper ultricies nisi.
<span><!--nesting levels:0-->Nam eget dui.</span>
Etiam rhoncus.
<span><!--nesting levels:1-->Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet
adipiscing sem neque sed ipsum.
<span><!--nesting levels:0-->Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.</span>
<span><!--nesting levels:0-->Maecenas nec odio et ante tincidunt tempus.</span>
Donec vitae sapien ut libero venenatis faucibus.
<span><!--nesting levels:0-->Nullam quis ante.</span>
</span>
Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet
nibh.
</span>
Donec sodales sagittis magna.
</div>
</text>
现在,我尝试了 count(descendant::span))
,但显然,这也会包括所有兄弟姐妹,并且在许多情况下会产生错误的结果。我还尝试了 count(descendant::span[1]))
和 count(descendant::span[position() = 1]))
,它们也给出了错误的结果。我还不知道如何从总数中排除兄弟姐妹的数量。任何提示表示赞赏。
在 XSLT 中,我使用表达式
获得了正确的值 max(
for $leaf in descendant-or-self::span[not(span)]
return count($leaf/ancestor-or-self::span except ancestor-or-self::span)
)
例如使用样式表
<?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"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="span">
<xsl:copy>
<xsl:attribute name="nesting-level"
select="
max(
for $leaf in descendant-or-self::span[not(span)]
return count($leaf/ancestor-or-self::span except ancestor-or-self::span)
)"/>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我得到了输出
<?xml version="1.0" encoding="UTF-8"?><text>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor. Aenean massa.
<span nesting-level="2"><!--nesting level:2-->Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<span nesting-level="1"><!--nesting levels:1-->Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
<span nesting-level="0"><!--nesting levels:0-->Nulla consequat massa quis enim.</span>
</span>
<span nesting-level="0"><!--nesting levels:0-->Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.</span>
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
</span>
<span nesting-level="0"><!--nesting levels:0-->Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus
elementum semper nisi.
</span>
<span nesting-level="0"><!--nesting levels:0-->Aenean vulputate eleifend tellus. Aenean leo ligula,
porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
quis, feugiat a, tellus.
</span>
</div>
<div>Phasellus viverra nulla ut metus varius laoreet.
<span nesting-level="0"><!--nesting levels:0-->Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
</span>
<span nesting-level="2"><!--nesting levels:2-->Curabitur ullamcorper ultricies nisi.
<span nesting-level="0"><!--nesting levels:0-->Nam eget dui.</span>
Etiam rhoncus.
<span nesting-level="1"><!--nesting levels:1-->Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet
adipiscing sem neque sed ipsum.
<span nesting-level="0"><!--nesting levels:0-->Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.</span>
<span nesting-level="0"><!--nesting levels:0-->Maecenas nec odio et ante tincidunt tempus.</span>
Donec vitae sapien ut libero venenatis faucibus.
<span nesting-level="0"><!--nesting levels:0-->Nullam quis ante.</span>
</span>
Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet
nibh.
</span>
Donec sodales sagittis magna.
</div>
</text>