XPath查找节点是否存在

209

如何使用XPath查找节点(标记)是否存在?

例如,如果我需要确保网站页面具有正确的基本结构,例如 /html/body/html/head/title


也许最好使用带有必填元素指示的XML模式?这样可以检查文档是否使用它。 - abatishchev
6个回答

333
<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>

4
@SearchForKnowledge,你最好在SO上提出这个问题,但是作为一个快速指南:html/body and not(html/body/node())(即仅测试它是否存在并且不包含任何子节点或文本节点)。 - Abel

76

请尝试使用以下表达式:boolean(节点路径)


3
在使用Python及lxml处理XPath时,这正是我需要的。 - Iain Samuel McLean Elder
1
在 InfoPath 2010 中构建规则条件和规则操作时,这个方法非常有效。 - Merenzo
4
这是正确答案,因为它实际上是一个XPath查询,而不像其他大多数答案。 - Paul Etherton

51

帕特里克是正确的,他在使用 xsl:if 中和检查节点存在的语法方面都是正确的。然而,正如帕特里克所暗示的那样,没有xsl等同于if-then-else。因此,如果你想要类似if-then-else的操作,通常最好使用 xsl:choosexsl:otherwise。所以,帕特里克的示例语法可以工作,但这是另一种选择:

<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" 放在第二个 when 中使其成为 if-else if-else 吗? - AabinGunz
4
@Abhishek 是的,你可以添加更多的 xsl:when 条件分支语句,形成一个多分支的语句。将其视为 SELECT 而不是 if-then-else,并将 xsl:otherwise 作为默认值。 - davenpcj
这很棒,但如果我想检查它是否存在或为空怎么办? - SearchForKnowledge

14

使用选择器可能更好,不必多次键入表达式(或可能出现的打字错误),并且允许您遵循其他不同的行为。

我经常使用count(/html/body) = 0,因为节点的具体数量比集合更有趣。例如...当有意外地有超过一个与您的表达式匹配的节点时。

<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子句来改变行为并以不同的方式处理多个条件。 - davenpcj
count(/html/body) = 0 太聪明啦! :D 当 /body (或其他元素) 缺失时,我使用它作为 /html[count(/body)=0]/someNode 来选择 someNode - Stefan Rogin
1
@clickstefan,“/html[count(/body)=0]”永远不会选择任何内容,在XML中不能有两个根节点。也许你的意思是“/html[count(body)=0]”,这与“/html[not(body)]”或“/html[not(exists(body))]”相同。 - Abel
@Abel 是的,/html[count(//body)=0] 或者你说的那样,很丢脸但是我没有给出一个恰当的例子。 - Stefan Rogin

4

我使用Ruby编程语言,并使用Nokogiri库获取元素,然后查看结果是否为空。

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?

3
在Java中使用xpath时,使用count()的一种变化形式:
int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接