首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XPath语法,带或不带"/text()“后缀

问XPath语法,带或不带"/text()“后缀
EN

Stack Overflow用户
提问于 2019-08-15 05:09:02
回答 2查看 375关注 0票数 2

从不同的网站,提供的XPath语法不同,主要是"/text()"后缀的需要。

引用没有的语法,需要后缀:

引用带有的语法,需要后缀:

据我所知,不同的库也只使用后缀或不带后缀(在使用和不使用后缀时,我都没有遇到过)。

不需要后缀:

需要后缀:

  • Java本机XPath实现

最有可能的是,XPath库实现与用于XML和DOM的实现有区别吗?如果是的话,有什么不同,我在哪里可以找到区别呢?

EN

回答 2

Stack Overflow用户

发布于 2019-08-15 08:14:35

我想你已经误诊了,而误诊的原因是你看了大约7名病人的症状,而不是去上医学院学习解剖学。

这里的“解剖”是XDM数据模型,它是XPath语义的基础。请特别注意:

(a)当你有这样的结构时

代码语言:javascript
复制
<title>Water</title>

有一个元素节点,其字符串值为“水”,它是单个文本节点的父节点,其字符串值也是“水”。

(b)当你有这样的结构时

代码语言:javascript
复制
<title>H<sub>2</sub>O</title>

有一个元素节点,其字符串值为"H2O",它是三个子节点的父节点:字符串值"H“的文本节点,字符串值"2”的元素节点(它本身是另一个文本节点的父节点.),以及字符串值"O“的第二个文本节点。

在(a)情况下,无论应用于元素节点还是文本节点,几乎所有操作都会产生相同的结果。例如,无论contains($x, "ate")是元素节点还是文本节点,$x都将为真。因此,将/text()添加到路径通常是多余的:它没有坏处,但它是不必要的。我们经常建议不要这样做,因为如果数据的结构后来发生变化,它会使您的代码更加脆弱,除了添加不必要的详细内容之外。

如果(b)在路径中添加/text()会导致您选择两个文本节点"H“和"O”,而不是选择元素节点。在XPath 1.0中,应用于两个文本节点序列的许多操作(如contains())忽略了除第一个节点之外的所有操作,因此contains(x/y/title/text(), "O")将返回false;在XPath 2.0中,它将抛出一个错误,说明false()的参数必须是单例。如果您只是想知道标题是否包含字母"O",那么最好省略/text()并将操作应用到元素的字符串值,即所有文本节点的连接。

唯一需要使用"/text()“的是如果您想更深入地研究title元素的内部结构。

当然,XPath实现之间可能存在差异--并不是所有的实现都100%符合标准。但是主流实现是相当兼容的,如果您发现了不同之处,请告诉我们:明确说明源文档、路径表达式以及在不同实现中获得的不同结果。

票数 3
EN

Stack Overflow用户

发布于 2019-08-15 21:18:38

如果查看相关规范,您会发现XPath 1.0 https://www.w3.org/TR/xpath-10/#node-tests以及XPath 2.0规范https://www.w3.org/TR/xpath20/#node-tests都将“后缀”定义为用于选择任何“文本节点”的“节点测试”text()。

没有一种规范要求使用text(),但当然,它是语言选择文本节点的一个选项,例如,在只有选择文本节点子节点的原因的情况下,元素和文本以及/或注释的内容混合在一起。

至于实现,我不认为Java的XPath 1.0实现需要您使用它,一些旧的DOM特定代码使用foo/text()而不是简单的foo来读取元素(例如<foo>some example</foo> )中的字符串内容的唯一原因是,对于较旧的DOM实现,如果选择Element节点,则没有属性或方法将元素的文本内容作为字符串访问,因此,人们使用foo/text()来选择Element的Text子节点,然后可以使用nodeValue属性(Javascript)或getNodeValue()方法(Java)获得带有some example的字符串。但是,DOM多年来一直在Element节点上提供属性Element,因此现在可以使用foo作为XPath并获取Element节点,并分别读出textContent或getTextContent()以获得字符串some example。

MSXML和XPath也相当古老,从未更新到DOMLevel3 W3C规范,但微软从一开始就在元素节点上拥有自己的私有.text属性,您可以在那里使用而不是标准化的textContent。然而,在这种情况下,我看到了类似的尝试,它们将foo/text()显式地读出为节点列表,然后可以将每个文本节点的nodeValue作为字符串访问。

我看到的使用foo/text()而不是foo的唯一实现特定的“首选项”是在Python的lxml库中,如果您希望将XPath选择直接映射到一个XPath字符串列表,在这种情况下,例如<data><foo>a</foo><foo>b</foo></data>上下文中的foo/text()表达式会给您提供一个包含两个a和b的Python字符串的列表,而使用foo则会给您一个包含两个元素节点的列表。因此,根据您在宿主语言方面的需要,在这种情况下,使用foo/text()可能更容易,但是您需要注意,像<data><foo>a<!-- comment -->b</foo><foo>c</foo></data>这样的输入会给出一个包含三个字符串的列表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57505091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档