找到一个只有另一种子元素的元素 [英] Find an element that only has one other kind of child

查看:23
本文介绍了找到一个只有另一种子元素的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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 a pre 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>

这篇关于找到一个只有另一种子元素的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆