【问题标题】:XPath - Difference between node() and text()XPath - node() 和 text() 之间的区别
【发布时间】:2012-07-31 16:09:46
【问题描述】:

我无法理解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>

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

任何帮助将不胜感激!

【问题讨论】:

    标签: xml xpath expression


    【解决方案1】:

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

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

    各种node tests

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

    此 XML 文档:

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

    表示以下 DOM(简化):

    根节点 元素节点(名称=“生产”) 文本节点(值=“\n”) 元素节点(名称=“项目”) 文本节点(值=“苹果”) 文本节点(值=“\n”) 元素节点(名称=“项目”) 文本节点(值=“香蕉”) 文本节点(值=“\n”) 元素节点(名称=“项目”) 文本节点 (value="pepper") 文本节点(值="\n")

    XPath 也是如此:

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

    等等。

    那么,你的问题

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

    注意事项

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

    【讨论】:

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

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

    <?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 中的内部标签中的文本”,但是,按原始顺序对文本进行排序变得具有挑战性,因为您不知道将内部标签中的聚合文本放在哪里!因为您不知道知道将聚合文本从内部节点放在哪里。

    1. U937 细胞感染 HIV-1 后,
    2. 未检测到 NF-KB 因子的诱导
    3. ,而产生高水平的后代病毒体,
    4. 表明病毒复制不需要此因素
    5. .

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-25
      • 2016-05-31
      • 1970-01-01
      • 2021-01-08
      • 1970-01-01
      • 2016-09-17
      • 2014-10-09
      • 2023-03-06
      相关资源
      最近更新 更多