xml 有没有更好的方法来获取 XPath 查询结果的父节点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12875203/
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 13:43:39  来源:igfitidea点击:

Is there a better way of getting parent node of XPath query result?

xmldomxpath

提问by Marcin Orlowski

Having markup like this:

有这样的标记:

<div class="foo">
   <div><span class="a1"></span><a href="...">...</a></div>
   <div><span class="a2"></span><a href="...">...</a></div>
   <div><span class="a1"></span>some text</div>
   <div><span class="a3"></span>some text</div>
</div>

I am interested in getting all <a>and some textONLYif adjacent spanis of class a1. So at the end of the whole code my result should be <a>from first divand some textfrom third one. It'd be easy if <a>and some textwere inside spanor divwould have classattribute, but no luck.

我有兴趣获得所有<a>并且some text当相邻span是 class 时a1。所以在整个代码的末尾,我的结果应该是<a>第一个divsome text第三个。如果<a>some text在里面span或者div会有class属性,那会很容易,但没有运气。

What I am doing now is look for spanwith a1class:

我现在正在做的就是寻找span具有a1类:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]

then I get its parent and do another query()with that parent as context node. This simply looks far from being efficient so the question clearly is if there is any better way to accomplish my goal?

然后我得到它的父级,并query()用该父级作为上下文节点做另一个。这看起来远非有效,所以问题显然是是否有更好的方法来实现我的目标?



THE ANSWER ADDENDUM

答案附录

As per @MarcB accepted answer, the right query to use is:

根据@MarcB接受的答案,要使用的正确查询是:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..

but for <a>it may be better to use:

但因为<a>它可能更好地使用:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/../a

the get the <a>instead of its container.

获取<a>而不是它的容器。

回答by Marc B

The nice thing about xpath queries is that you can essentially treat them like a file system path, so simply having

xpath 查询的好处在于,您基本上可以将它们视为文件系统路径,因此只需拥有

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..
                                                              ^^

will find all your .a1 nodes that are below a .foo node, then move up one level to the a1 nodes' parents.

将找到所有低于 .foo 节点的 .a1 节点,然后向上移动一级到 a1 节点的父节点。

回答by Dimitre Novatchev

An expression that is betterthan using reverse axis:

一个比使用反向轴更好的表达式

//div[contains(@class,'foo')]/div[span[contains(@class,'a1')]]

This selects any divthat is a child of a divwhose classattribute contains the string "foo" and that (the selected div) has a spanchild whose classattribute contains the string "a1".

这个选择任何div也就是说的儿童的div,其class属性包含字符串“foo”,并且(所选div)具有span子,其class属性包含字符串“A1”。

XSLT - based verification:

基于 XSLT 的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "//div[contains(@class,'foo')]
          /div[span[contains(@class,'a1')]]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

当此转换应用于提供的 XML 文档时:

<div class="foo">
   <div><span class="a1"></span><a href="...">...</a></div>
   <div><span class="a2"></span><a href="...">...</a></div>
   <div><span class="a1"></span>some text</div>
   <div><span class="a3"></span>some text</div>
</div>

the XPath expression is evaluated and the selected elements are copied to the output:

计算 XPath 表达式并将所选元素复制到输出:

<div>
   <span class="a1"/>
   <a href="...">...</a>
</div>
<div>
   <span class="a1"/>some text</div>


II. Remarks on accessing an Html element by one of its classes:

二、关于通过其类之一访问 Html 元素的说明

If it is known that the element can have only one class, then it isn't necessary at all to use contains()

如果知道元素只能有一个类,那么根本没有必要使用 contains()

Don't use:

不要使用

//div[contains(@class, 'foo')]

Use:

使用

//div[@class = 'foo']

or, if there could be leading/trailing spaces, use:

或者,如果可能有前导/尾随空格,请使用:

//div[normalize-space(@class) = 'foo']

A crucial issue with:

一个关键问题

//div[contains(@class, 'foo')]

is that this selects any divwith class such as "myfoo", "foo2" or "myfoo3".

是这选择任何div类,例如“myfoo”、“foo2”或“myfoo3”。

If the element may have more than one class, and to avoid the above issue, the correct XPath expression is:

如果元素可能有多个类,并且为了避免上述问题,正确的 XPath 表达式为

//div[contains(concat(' ', @class, ' '), ' foo ')]