xml XPath - node() 和 text() 之间的区别

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

XPath - Difference between node() and text()

xmlxpathexpression

提问by Pztar

I'm having trouble understanding the difference between text()and node(). From what I understand, text()would be whatever is in between the tags <item>apple</item>which is applein this case. Node would be whatever that node actually is, which would be item

我无法理解之间的差异text()node()。据我所知,在这种情况下text(),标签之间的任何东西<item>apple</item>都是苹果。节点将是该节点实际是什么,这将是项目

But then I've been assigned some work where it asks me to "Select the text of all items under produce" and a separate question asks "Select all the manager nodes in all departments"

但是后来我被分配了一些工作,它要求我“选择生产下所有项目的文本”,一个单独的问题询问“选择所有部门中的所有管理节点”

How is the output suppose to look text()as opposed to node()

输出看起来如何text(),而不是node()

Snippet of XML:

XML 片段:

<produce>
 <item>apple</item>
 <item>banana</item>
 <item>pepper</item>
</produce>

<department>
 <phone>123-456-7891</phone>
 <manager>John</manager>
</department>

Of course, there are more departments and more managers, but this was just a snippet of code.

当然,还有更多的部门和更多的经理,但这只是一小段代码。

Any help would be much appreciated!

任何帮助将非常感激!

回答by Tomalak

text()and node()are node tests, in XPath terminology (compare).

text()并且node()节点测试,在 XPath 术语中(比较)。

Node tests operate on a set (on an axis, to be exact) of nodes and return the ones that are of a certain type. When no axis is mentioned, the childaxis is assumed by default.

节点测试在一组(准确地说是在轴上)节点上运行,并返回特定类型的节点。当未提及child轴时,默认采用轴。

There are all kinds of node tests:

有各种节点测试

  • node()matches anynode (the least specific node test of them all)
  • text()matches textnodes only
  • comment()matches commentnodes
  • *matches any elementnode
  • foomatches any element node named "foo"
  • processing-instruction()matches PI nodes (they look like <?name value?>).
  • Side note:The *also matches attribute nodes, but only along the attributeaxis. @*is a shorthand for attribute::*. Attributes are not part of the childaxis, that's why a normal *does not select them.
  • node()匹配任何节点(所有节点中最不具体的节点测试)
  • text()仅匹配文本节点
  • comment()匹配评论节点
  • *匹配任何元素节点
  • foo匹配任何名为的元素节点 "foo"
  • processing-instruction()匹配 PI 节点(它们看起来像<?name value?>)。
  • 附注:*也匹配属性节点,但仅沿attribute轴线。@*是 的简写attribute::*。属性不是child轴的一部分,这就是法线*不选择它们的原因。

This XML document:

此 XML 文档:

<produce>
    <item>apple</item>
    <item>banana</item>
    <item>pepper</item>
</produce>

represents the following DOM (simplified):

代表以下 DOM(简化):

root node
   element node (name="produce")
      text node (value="\n    ")
      element node (name="item")
         text node (value="apple")
      text node (value="\n    ")
      element node (name="item")
         text node (value="banana")
      text node (value="\n    ")
      element node (name="item")
         text node (value="pepper")
      text node (value="\n")

So with XPath:

所以使用 XPath:

  • /selects the root node
  • /produceselects a child element of the root node if it has the name "produce"(This is called the document element; it represents the document itself. Document element and root node are often confused, but they are not the same thing.)
  • /produce/node()selects any type of child nodebeneath /produce/(i.e. all 7 children)
  • /produce/text()selects the 4 (!) whitespace-only text nodes
  • /produce/item[1]selects the first child element named "item"
  • /produce/item[1]/text()selects allchild text nodes (there's only one - "apple" - in this case)
  • /选择根节点
  • /produce选择根节点的子元素,如果它有名字"produce"(这称为文档元素;它代表文档本身。文档元素和根节点经常混淆,但它们不是一回事。)
  • /produce/node()选择任何类型的子节点的下方/produce/(即,所有7个孩子)
  • /produce/text()选择 4 (!) 个纯空白文本节点
  • /produce/item[1]选择第一个名为的子元素 "item"
  • /produce/item[1]/text()选择所有子文本节点(只有一个 - “apple” - 在这种情况下)

And so on.

等等。

So, your questions

所以,你的问题

  • "Select the text of all items under produce"/produce/item/text()(3 nodes selected)
  • "Select all the manager nodes in all departments"//department/manager(1 node selected)
  • “选择生产下所有项目的文本”/produce/item/text()(选择了3个节点)
  • “选择所有部门的所有管理节点”//department/manager(选择1个节点)

Notes

笔记

  • The default axisin XPath is the childaxis. You can change the axis by prefixing a different axis name. For example: //item/ancestor::produce
  • Element nodes have text values. When you evaluate an element node, its textual contents will be returned. In case of this example, /produce/item[1]/text()and string(/produce/item[1])will be the same.
  • Also see this answerwhere I outline the individual parts of an XPath expression graphically.
  • XPath 中的默认child轴。您可以通过为不同的轴名称添加前缀来更改轴。例如://item/ancestor::produce
  • 元素节点具有文​​本值。当您评估元素节点时,将返回其文本内容。在这个例子的情况下,/produce/item[1]/text()string(/produce/item[1])将是相同的。
  • 另请参阅此答案,其中我以图形方式概述了 XPath 表达式的各个部分。

回答by Danil Speransky

Select the text of all items under produce:

选择产品下所有项目的文本:

//produce/item/text()

Select all the manager nodes in all departments:

选择所有部门的所有管理节点:

//department/*