XPath 查找节点是不是存在
Posted
技术标签:
【中文标题】XPath 查找节点是不是存在【英文标题】:XPath find if node existsXPath 查找节点是否存在 【发布时间】:2010-10-20 13:14:08 【问题描述】:使用 XPath 查询如何确定节点(标签)是否存在?
例如,如果我需要确保网站页面具有正确的基本结构,例如 /html/body
和 /html/head/title
。
【问题讨论】:
也许最好使用带有强制性元素指示的 XML Schema?因此,请检查文档是否使用它。 【参考方案1】:<xsl:if test="xpath-expression">...</xsl:if>
例如
<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
【讨论】:
对如此高的评价感到惊讶,因为问题根本没有指定 XSLT 的使用。 @SearchForKnowledge,您可能应该在 SO 提出一个新问题,但作为快速指南:html/body and not(html/body/node())
(即,只需测试它是否存在并且它不包含任何子节点,或者文本节点)。【参考方案2】:
试试下面的表达式:boolean(path-to-node)
【讨论】:
这正是我在带有 lxml 的 Python 中使用 XPath 时所需要的。 这在 InfoPath 2010 中构建规则条件和规则操作时非常有用。 这是正确的答案,因为这实际上是一个 XPath 查询,与大多数其他答案不同。【参考方案3】:Patrick 是正确的,在xsl:if
的使用和检查节点是否存在的语法中都是正确的。但是,正如 Patrick 的回答所暗示的,没有与 if-then-else 等效的 xsl,因此,如果您正在寻找更像 if-then-else 的东西,通常最好使用xsl:choose
和xsl:otherwise
。因此,Patrick 的示例语法将起作用,但这是另一种选择:
<xsl:choose>
<xsl:when test="/html/body">body node exists</xsl:when>
<xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
【讨论】:
+1 表示关注if-then-else
,那么if-else if-else
呢?在 davenpcj 的回答中,我可以将 test="somexpath"
放在第二个什么时候让它成为 if-else if-else
?
@Abhishek 是的,你可以放更多的 xsl:when 与其他条件,并有一个多分支语句。把它想象成 SELECT 而不是 if-then-else,xsl:otherwise 作为默认值:。
这很棒,但如果我想检查它是否存在或为空怎么办?【参考方案4】:
使用选项可能会更好,不必多次输入(或可能错误输入)您的表达式,并允许您遵循其他不同的行为。
我经常使用count(/html/body) = 0
,因为具体的节点数量比集合更有趣。例如...当意外超过 1 个节点与您的表达式匹配时。
<xsl:choose>
<xsl:when test="/html/body">
<!-- Found the node(s) -->
</xsl:when>
<!-- more xsl:when here, if needed -->
<xsl:otherwise>
<!-- No node exists -->
</xsl:otherwise>
</xsl:choose>
【讨论】:
如上面的代码所示,可以添加更多的 xsl:when 子句来改变行为并以不同的方式处理多个条件。count(/html/body) = 0
天才! :D 当/body
(或其他)丢失时,我将它用作/html[count(/body)=0]/someNode
来选择someNode
@clickstefan, /html[count(/body)=0]
永远不会选择任何东西,XML 中不能有两个根节点。也许您的意思是/html[count(body)=0]
,它与/html[not(body)]
或/html[not(exists(body))]
相同。
@Abel 是的,/html[count(//body)=0] 或者你说的,可耻,但是是的,我没有给出适当的例子【参考方案5】:
我在 Ruby 中工作并使用 Nokogiri 获取元素并查看结果是否为 nil。
require 'nokogiri'
url = "http://somthing.com/resource"
resp = Nokogiri::XML(open(url))
first_name = resp.xpath("/movies/actors/actor[1]/first-name")
puts "first-name not found" if first_name.nil?
【讨论】:
【参考方案6】:使用 count() 在 Java 中使用 xpath 时的变体:
int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0)
// body node missing
【讨论】:
以上是关于XPath 查找节点是不是存在的主要内容,如果未能解决你的问题,请参考以下文章