说我有一对XML文档
<Foo>
<Bar/>
<Baz>mystring</Baz>
</Foo>
和
<Foo>
<Bar/>
</Foo>
我想要一个XPath(仅限1.0版),它为第一个文档返回“mystring”,为第二个文档返回“not-found”。我试过了
(string('not-found') | //Baz)[last()]
但联盟的左侧不是节点集
答案 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;”替换空字符串。