xml XPath 选择多个标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/721928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 12:26:18  来源:igfitidea点击:

XPath to select multiple tags

xmlxpath

提问by nickf

Given this simplified data format:

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

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

How would you select all the Cs, Ds and Es that are children of Belements?

您将如何选择作为元素子元素的所有Cs、Ds 和Es B

Basically, something like:

基本上,类似于:

a/b/(c|d|e)

In my own situation, instead of just a/b/, the query leading up to selecting those C, D, Enodes is actually quite complex so I'd like to avoid doing this:

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

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

Is this possible?

这可能吗?

回答by Dimitre Novatchev

One correct answer is:

一个正确的答案是

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

Do note that this

请注意,这

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

is both too-long and incorrect. This XPath expression will select nodes like:

既太长又不正确。此 XPath 表达式将选择如下节点:

OhMy:c

NotWanted:d 

QuiteDifferent:e

回答by annakata

You can avoid the repetition with an attribute test instead:

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

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

Contrary to Dimitre's antagonistic opinion, the above is not incorrectin a vacuum where the OP has not specified the interaction with namespaces. The self::axis is namespace restrictive, local-name()is not. If the OP's intention is to capture c|d|eregardless of namespace (which I'd suggest is even a likely scenario given the OR nature of the problem) then it is "another answer that still has some positive votes" which is incorrect.

与 Dimitre 的反对意见相反,在 OP 没有指定与命名空间的交互的真空中,上述内容并没有错。该self::轴是命名空间限制性的,local-name()是没有的。如果 OP 的意图是不c|d|e考虑名称空间而进行捕获(鉴于问题的 OR 性质,我认为这甚至是一种可能的情况)那么它是“另一个仍然有一些赞成票的答案”,这是不正确的。

You can't be definitive without definition, though I'm quite happy to delete my answer as genuinely incorrect if the OP clarifies his question such that I am incorrect.

如果没有定义,你就不能确定,尽管如果 OP 澄清了他的问题,我很高兴将我的答案删除为真正不正确的答案。

回答by Pavel Repin

Why not a/b/(c|d|e)? I just tried with Saxon XML library(wrapped up nicely with some Clojure goodness), and it seems to work. abc.xmlis the doc described by OP.

为什么不a/b/(c|d|e)呢?我刚刚尝试了Saxon XML 库(用一些 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>>)

回答by Calvin

Not sure if this helps, but with XSL, I'd do something like:

不确定这是否有帮助,但是使用 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>

and won't this XPath select all children of B nodes:

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

a/b/*