问题描述
我想使用 XPath 查找每个
子元素,没有其他类型的子元素,并且可选的文本节点作为子节点:
<blockquote><pre>YES</pre></blockquote><blockquote><p>NO</p></blockquote><blockquote><pre>NO</pre><p>NO</p></blockquote><blockquote><p>NO</p><pre>NO</pre></blockquote><blockquote><pre>YES</pre><pre>YES</pre></blockquote><blockquote>NO</blockquote></div></body>
这个 XPath 似乎有效,但我怀疑它过于复杂:
//blockquote[pre][not(*[not(name()="pre")])]
是否有更好(更少代码、更高效、更 DRY)的方式来选择我想要的东西?
解决方案使用:
//blockquote[* and not(*[not(self::pre)])]
这将选择 XML 文档中的所有
blockquote
元素,这些元素至少有一个子元素,并且没有任何不是pre
元素的子元素.这只是双重否定法则 :).
请注意,此表达式比计算所有元素子元素的表达式更有效(因为选择会在找到非
pre
子元素的那一刻停止).基于 XSLT 的验证:
<xsl:output omit-xml-declaration="yes" indent="yes"/><xsl:strip-space elements="*"/><xsl:template match="/"><xsl:copy-of select="//blockquote[* and not(*[not(self::pre)])]"/></xsl:模板></xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<blockquote><pre>YES</pre></blockquote><blockquote><p>NO</p></blockquote><blockquote><pre>NO</pre><p>NO</p></blockquote><blockquote><p>NO</p><pre>NO</pre></blockquote><blockquote><pre>YES</pre><pre>YES</pre></blockquote><blockquote>NO</blockquote></div></body>
计算 XPath 表达式并将所选节点复制到输出:
<pre>是</pre></blockquote><blockquote><pre>是</pre><pre>是</pre></blockquote>
I want to use XPath to find every
<blockquote>
element that has at least one child<pre>
element, no other kinds of child elements, and optionally text nodes as children:<body><div><!-- arbitrary nesting --> <blockquote><pre>YES</pre></blockquote> <blockquote><p>NO</p></blockquote> <blockquote><pre>NO</pre><p>NO</p></blockquote> <blockquote><p>NO</p><pre>NO</pre></blockquote> <blockquote><pre>YES</pre> <pre>YES</pre></blockquote> <blockquote>NO</blockquote> </div></body>
This XPath appears to work, but I suspect that it's overly complicated:
//blockquote[pre][not(*[not(name()="pre")])]
Is there a better (less code, more efficient, more DRY) way to select what I want?
解决方案Use:
//blockquote[* and not(*[not(self::pre)])]
This selects all
blockquote
elements in the XML document that have at least one element child and don't have any element child that isn't apre
element.This is just an application of the double negation law :).
Do note, that this expression is more efficient than one that counts all element children (because the selection stops right at the moment a non-
pre
child is found).XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <xsl:copy-of select="//blockquote[* and not(*[not(self::pre)])]"/> </xsl:template> </xsl:stylesheet>
When this transformation is applied on the provided XML document:
<body><div><!-- arbitrary nesting --> <blockquote><pre>YES</pre></blockquote> <blockquote><p>NO</p></blockquote> <blockquote><pre>NO</pre><p>NO</p></blockquote> <blockquote><p>NO</p><pre>NO</pre></blockquote> <blockquote><pre>YES</pre> <pre>YES</pre></blockquote> <blockquote>NO</blockquote> </div></body>
the XPath expression is evaluated and the selected nodes are copied to the output:
<blockquote> <pre>YES</pre> </blockquote> <blockquote> <pre>YES</pre> <pre>YES</pre> </blockquote>
这篇关于找到一个只有另一种子元素的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!