ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

XML 片段:

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

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

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

任何帮助将非常感激!


C
Community

text()node() 在 XPath 术语 (compare) 中是 节点测试

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

有各种 node tests

node() 匹配任何节点(所有节点中最不具体的节点测试)

text() 仅匹配文本节点

comment() 匹配评论节点

匹配任何元素节点

foo 匹配任何名为“foo”的元素节点

processing-instruction() 匹配 PI 节点(它们看起来像 )。

旁注:* 也匹配属性节点,但仅沿着属性轴。 @* 是属性::* 的简写。属性不是子轴的一部分,这就是普通 * 不选择它们的原因。

此 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个节点)

"选择所有部门的所有经理节点" //部门/经理(选择了1个节点)

笔记

XPath 中的默认轴是子轴。您可以通过为不同的轴名称添加前缀来更改轴。例如://item/ancestor::produce

元素节点具有文本值。评估元素节点时,将返回其文本内容。在此示例中,/produce/item[1]/text() 和 string(/produce/item[1]) 将是相同的。

另请参阅此答案,其中我以图形方式概述了 XPath 表达式的各个部分。


这是一个很好的答案,但为了记录,有几个不准确之处。 (a) node-test "*" 的含义取决于轴:对于大多数轴,它选择元素节点,但对于属性轴,它选择属性,对于名称空间轴,它选择名称空间。 (b) @*@foo 不是节点测试,而是轴步骤,由两部分组成:轴(@attribute:: 的缩写)和节点测试(*foo)。
@MichaelKay 谢谢你的澄清。我将修改误导性位。无论如何,轴都超出了这个问题的范围,但是一旦您谈论 XPath,就很难避免提及它们。
@tomalak 那么上面的注释部分是如何定义的(即:<!-- --->)?
J
Jason Angel

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

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

我需要提取标签之间的文本并聚合(通过连接)包括内部标签在内的文本。

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

/text() 只返回不包含在内部标签中的文本,因为内部标签不是“文本节点”。您可能会想,“只提取包含在附加 xpath 中的内部标签中的文本”,但是,按原始顺序对文本进行排序变得具有挑战性,因为您不知道将内部标签中的聚合文本放置在哪里!因为您不知道知道在哪里放置来自内部节点的聚合文本。

当 U937 细胞被 HIV-1 感染时,没有检测到 NF-KB 因子的诱导,而产生了高水平的后代病毒粒子,这表明该因子不是病毒复制所必需的。

最后,/node() 完全符合我的要求,因为它也从内部标签中获取文本。