XPath选择多个标签

时间:2009-04-06 15:18:24

标签: xml xpath

鉴于这种简化的数据格式:

<a>
    <b>
        <c>C1</c>
        <d>D1</d>
        <e>E1</e>
        <f>don't select this one</f>
    </b>
    <b>
        <c>C2</c>
        <d>D2</d>
        <e>E1</e>
        <g>don't select me</g>
    </b>
    <c>not this one</c>
    <d>nor this one</d>
    <e>definitely not this one</e>
</a>

您如何选择C元素的所有DEB

基本上是这样的:

a/b/(c|d|e)

在我自己的情况下,而不仅仅是a/b/,导致选择那些CDE节点的查询实际上非常复杂,所以我会喜欢避免这样做:

a/b/c|a/b/d|a/b/e

这可能吗?

4 个答案:

答案 0 :(得分:185)

一个正确的答案是

/a/b/*[self::c or self::d or self::e]

请注意

a/b/*[local-name()='c' or local-name()='d' or local-name()='e']

太长且不正确。此XPath表达式将选择以下节点:

OhMy:c

NotWanted:d 

QuiteDifferent:e

答案 1 :(得分:42)

您可以使用属性测试来避免重复:

a/b/*[local-name()='c' or local-name()='d' or local-name()='e']

与Dimitre的对立观点相反,上述情况不正确在真空中,OP尚未指定与名称空间的交互。 self::轴是名称空间限制,local-name()不是。如果OP的意图是捕获c|d|e而不管命名空间(我建议甚至可能出现问题的OR性质)那么它是“另一个仍有一些积极投票的答案”,这是不正确的

如果没有定义,你不可能是明确的,但如果OP澄清他的问题使我不正确,我很乐意将我的答案删除为真的不正确。

答案 2 :(得分:12)

为什么不a/b/(c|d|e)?我只是尝试了Saxon XML library(很好地包裹了一些Clojure善良),它似乎有效。 abc.xml是OP描述的文档。

(require '[saxon :as xml])
(def abc-doc (xml/compile-xml (slurp "abc.xml")))
(xml/query "a/b/(c|d|e)" abc-doc)
=> (#<XdmNode <c>C1</c>>
    #<XdmNode <d>D1</d>>
    #<XdmNode <e>E1</e>>
    #<XdmNode <c>C2</c>>
    #<XdmNode <d>D2</d>>
    #<XdmNode <e>E1</e>>)

答案 3 :(得分:-1)

不确定这是否有帮助,但是对于XSL,我会做类似的事情:

<xsl:for-each select="a/b">
    <xsl:value-of select="c"/>
    <xsl:value-of select="d"/>
    <xsl:value-of select="e"/>
</xsl:for-each>

并且此XPath不会选择B节点的所有子节点:

a/b/*