如果节点不存在,则XPath返回默认值

时间:2010-12-20 13:16:09

标签: xpath

说我有一对XML文档

<Foo>
    <Bar/>
    <Baz>mystring</Baz>
</Foo>

<Foo>
    <Bar/>
</Foo>

我想要一个XPath(仅限1.0版),它为第一个文档返回“mystring”,为第二个文档返回“not-found”。我试过了

(string('not-found') | //Baz)[last()]

但联盟的左侧不是节点集

5 个答案:

答案 0 :(得分:17)

在XPath 1.0中,使用:

concat(/Foo/Baz,
       substring('not-found', 1 div not(/Foo/Baz)))

如果要处理可能的空Baz元素,请使用:

concat(/Foo/Baz,
       substring('not-found', 1 div not(/Foo/Baz[node()])))

使用此输入:

<Foo>
    <Baz/>
</Foo>

结果:not-found字符串数据类型。

答案 1 :(得分:13)

特例: 如果想要在数字节点丢失或为空时获得0,请使用“sum(/ Foo / Baz)”函数

答案 2 :(得分:8)

@Alejandro提供了最好的XPath 1.0答案,自从first used by Jeni Tennison差不多十年前就知道了多年

这个表达式的唯一问题是它的闪亮优雅,这使得它不仅不被新手程序员理解。

在托管的XPath 1.0中(每个XPath都托管!)可以使用更易理解的表达式

string((/Foo/Baz | $vDefaults[not(/Foo/Baz/text())]/Foo/Baz)[last())

此处变量$vDefaults是一个单独的文档,其结构与主XML文档相同,其文本节点包含默认值。

或者,如果XSLT是托管语言,可以使用document()函数

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output  method="text"/>

 <my:defaults>
    <Foo>
        <Bar/>
        <Baz>not-found</Baz>
  </Foo>
 </my:defaults>

 <xsl:template match="/">
     <xsl:value-of select=
     "concat(/Foo/Baz,
           document('')[not(current()/Foo/Baz/text())]
                                        /*/my:defaults/Foo/Baz
           )"/>
 </xsl:template>
</xsl:stylesheet>

或者,不使用concat()

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output  method="text"/>

 <my:defaults>
    <Foo>
        <Bar/>
        <Baz>not-found</Baz>
  </Foo>
 </my:defaults>

 <xsl:variable name="vDefaults" select="document('')/*/my:defaults"/>

 <xsl:template match="/">
     <xsl:value-of select=
     "(/Foo/Baz 
       | $vDefaults/Foo/Baz[not(current()/Foo/Baz/text())]
       )
        [last()]"/>
 </xsl:template>
</xsl:stylesheet>

答案 3 :(得分:1)

/Foo/(Baz/string(), 'not-found')[1]

答案 4 :(得分:1)

如果您可以打印空字符串而不是“未找到”字样。消息然后使用:

/Foo/concat(Baz/text(), '')

稍后,您可以使用“未找到&#39;”替换空字符串。