【问题标题】:XPATH to select parent node along with child nodeXPATH 选择父节点和子节点
【发布时间】:2017-07-01 00:01:45
【问题描述】:

我有下面的 xml 文件,我想使用 XPATH 选择主机名、实例名称、实例类型

<root>
<hosts>
    <host id="11">
        <name>ABC</name>
        <instances>
            <instance id="11-1">
                <name>raj</name>
                <type>linux</type>
                <date>2017</date>
            </instance>
            <instance id="11-2">
                <name>raj1</name>
                <type>linux</type>
                <date>2017</date>
            </instance>
        </instances>
    </host>
    <host id="12">
        <name>XYZ</name>
        <instances>
            <instance id="12-1">
                <name>rahul</name>
                <type>solaris</type>
                <date>2017</date>
            </instance>
        </instances>
    </host>
</hosts>
</root>

我在 XPATH 下尝试过,它正在选择实例名称和类型,但不确定如何打印主机名以及实例名称和类型。

//hosts/host/instances/instance/*[self::name or self:: type]/text()

它选择以下结果。

    raj
    linux
    raj1
    linux
    rahul
    solaris

但是,我想要如下所示的包含主机名的输出

    ABC
    raj
    linux
    raj1
    linux
    XYZ
    rahul
    solaris

【问题讨论】:

  • 仅供参考,// 在这里非常昂贵——它告诉您的 XPath 引擎它需要在树中的任何位置搜索 hosts 元素,而不仅仅是在 root 的正下方。在某些引擎中,有一个用于这种查找的索引(想到 BaseX),但这绝不是一个通用功能。
  • (所以如果效率对您很重要,请考虑使用/root/hosts 而不是//hosts)。

标签: xml xpath


【解决方案1】:

以下(使用| 运算符组合由三个查询中的任何一个选择的元素集)将可以:

  //hosts/host[./instances/instance/name or ./instances/instance/type]/name/text()
| //hosts/host/instances/instance/name/text()
| //hosts/host/instances/instance/type/text()

【讨论】:

    【解决方案2】:

    如果您还想包含 hostname 的输出,请尝试以下操作:

    //hosts/host//*[self::name or self:: type]/text()
    

    【讨论】:

    • 嗯。这可能会做 OP 想要 做的事情,但不会做他们 指定 做的事情(如果按字面意思阅读,则表明只有 names 位于host 有一个 nametype 附加到一个 instance 应该包括)。
    • 是的,如果type 节点位于host 下,这可能会返回错误输出...否则这应该是一个可接受的解决方案
    • 我更关心是否应该包括没有实例的hostname - 我阅读 OP 的方式他们暗示它不应该,尽管这可能很可能是他们选择提出问题的方式的意外后果。
    【解决方案3】:

    您可以使用以下任何一种解决方案来达到您想要的结果 -

    解决方案 - 1(完整路径) - 您可以跳过根目录:

    /root/hosts/host/name[text()]|/root/hosts/host/instances/instance/*[self::name or self::type]

    解决方案 - 2(完整路径),对每个结果进行单独查询:

    /root/hosts/host/name[text()] |/root/hosts/host/instances/instance/name[text()]|/root/hosts/host/instances/instance/type[text( )]

    解决方案 - 3(节点路径)

    //host/name[text()]|//instance/*[self::name |自我::类型]

    解决方案 - 4(节点路径)

    //主机/[self::name]|//instance/[self::name |自我::类型]

    希望以上内容对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多