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

时间:2012-07-31 16:09:46

标签: xml xpath expression

我无法理解text()node()之间的区别。根据我的理解,text()将是标记<item>apple</item>之间的任何内容,在这种情况下是 apple 。节点将是节点实际上的任何节点,即

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

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

XML片段:

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

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

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

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:119)

在XPath术语(compare)中,

text()node()节点测试

节点测试对一组(准确地说是axis)节点进行操作,并返回某些类型的节点。如果未提及轴,则默认采用child轴。

有各种node tests

  • node()匹配任何节点(所有节点的最不具体的节点测试)
  • text()仅匹配 text 节点
  • comment()匹配评论节点
  • *匹配任何元素节点
  • foo匹配名为"foo"
  • 的任何元素节点
  • processing-instruction()匹配PI节点(它们看起来像<?name value?>)。
  • 旁注: *也匹配属性节点,但仅限于attribute轴。 @*attribute::*的简写。属性不是child轴的一部分,这就是普通*不选择它们的原因。

此XML文档:

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

表示以下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")

所以使用XPath:

  • /选择根节点
  • /produce选择根节点的子元素,如果它具有名称"produce"(这称为文档元素;它表示文档本身。文档元素和根节点经常被混淆,但它们不是一回事。)
  • /produce/node()/produce/下选择任意类型的子节点(即所有7个孩子)
  • /produce/text()选择4(!)仅空白文本节点
  • /produce/item[1]选择名为"item"
  • 的第一个子元素
  • /produce/item[1]/text()选择所有子文本节点(在这种情况下只有一个 - “apple”)

等等。

那么,你的问题

  • “选择生产中的所有项目的文本” /produce/item/text()(选择3个节点)
  • “选择所有部门中的所有经理节点” //department/manager(已选择1个节点)

注释

  • XPath中的默认child轴。您可以通过为不同的轴名称添加前缀来更改轴。例如://item/ancestor::produce
  • 元素节点具有文​​本值。评估元素节点时,将返回其文本内容。如果是此示例,则/produce/item[1]/text()string(/produce/item[1])将相同。
  • 另请参阅this answer,其中我以图形方式概述了XPath表达式的各个部分。

答案 1 :(得分:1)

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

//produce/item/text()

选择所有部门中的所有经理节点:

//department/*

答案 2 :(得分:0)

对我来说,面对这种情况有很大的不同(这里是我的故事:)

<?xml version="1.0" encoding="UTF-8"?>
<sentence id="S1.6">When U937 cells were infected with HIV-1, 
        
    <xcope id="X1.6.3">
        <cue ref="X1.6.3" type="negation">no</cue> 
                        
                        induction of NF-KB factor was detected
        
    </xcope>
                    
, whereas high level of progeny virions was produced, 
        
    <xcope id="X1.6.2">
        <cue ref="X1.6.2" type="speculation">suggesting</cue> that this factor was 
        <xcope id="X1.6.1">
            <cue ref="X1.6.1" type="negation">not</cue> required for viral replication
        </xcope>
    </xcope>.

</sentence>

我需要提取标签之间的文本,并(通过concat)聚合包含在内部标签中的文本。

/node()完成了工作,而/text()完成了一半工作

/text()仅返回内部标签中未包含的文本,因为内部标签不是“文本节点”。您可能会认为,“只是在其他xpath中提取包含在内部标签中的文本”,但是,以这种原始顺序对文本进行排序变得具有挑战性,因为您不知道将内部文本中的聚合文本放置在何处!知道从内部节点放置聚合文本的位置。

  1. 当U937细胞感染HIV-1时,
  2. 未检测到NF-KB因子的诱导
  3. ,虽然产生了高水平的后代病毒体,
  4. 建议病毒复制不需要该因子

最后,/node()确实做了我想要的,因为它也从内部标记中获取了文本。