You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过XPath查询XML匹配节点及其所有上级父节点(直至根节点)

获取XML目标节点及其所有非根父节点的属性值(XPath方案)

针对需求——定位目标节点后,输出该节点及所有非根父节点的@name属性,且无需提前固定层级结构,以下是几种可行方案:

1. XPath 2.0+ 原生递归表达式

如果你的工具支持XPath 2.0或更高版本(如Saxon、部分版本的xmlstarlet),可以直接用递归匹配表达式一次性获取所有目标属性:

//cup[@name='Shiny cup']/ancestor-or-self::*[not(local-name()='myStuff')]/@name

表达式说明:

  • ancestor-or-self::*:匹配当前节点(目标cup节点)及其所有祖先节点
  • [not(local-name()='myStuff')]:过滤掉根节点myStuff
  • /@name:提取符合条件节点的name属性

执行后会直接返回期望结果:

"Shiny cup",
"Left Compartment",
"Upper Shelf",
"Yellow Cupboard",
"Kitchen"

2. XPath 1.0 结合工具循环(兼容xmllint/xmlstarlet)

若只能用XPath 1.0(比如xmllint默认支持的版本),可以结合工具的多匹配模式或shell循环实现:

用xmlstarlet实现

xmlstarlet sel -t \
  -m "//cup[@name='Shiny cup']" -v "@name" -n \
  -m "//cup[@name='Shiny cup']/ancestor::*[not(local-name()='myStuff')]" -v "@name" -n \
  input.xml

命令说明:

  • 第一部分-m "//cup[@name='Shiny cup']" -v "@name" -n:输出目标节点的name属性
  • 第二部分-m "//cup[@name='Shiny cup']/ancestor::*[not(local-name()='myStuff')]" -v "@name" -n:遍历所有非根父节点,依次输出它们的name属性

用xmllint结合shell循环实现

#!/bin/bash
INPUT_FILE="input.xml"
CURRENT_NODE="//cup[@name='Shiny cup']"

# 循环遍历节点及父节点,直到遇到myStuff
while true; do
  # 输出当前节点的name属性(处理xmlstarlet输出格式)
  xmllint --xpath "$CURRENT_NODE/@name" "$INPUT_FILE" | sed 's/ name="//;s/"//'
  echo
  # 切换到父节点
  CURRENT_NODE="$CURRENT_NODE/.."
  # 获取父节点的标签名
  PARENT_TAG=$(xmllint --xpath "name($CURRENT_NODE)" "$INPUT_FILE")
  # 遇到myStuff则终止循环
  if [ "$PARENT_TAG" = "myStuff" ]; then
    break
  fi
done

3. 编程语言中递归遍历(以Python lxml为例)

如果是在代码里处理,直接递归遍历父节点是最灵活的方式:

from lxml import etree

# 加载XML文档
tree = etree.parse("input.xml")
# 定位目标节点
target_node = tree.xpath("//cup[@name='Shiny cup']")[0]

# 收集属性值
name_list = []
current = target_node
while current.tag != "myStuff":
    name_list.append(current.get("name"))
    current = current.getparent()

# 按目标格式输出
print('\n'.join(f'"{name}"' for name in name_list))

内容的提问来源于stack exchange,提问作者Kurtibert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:50:57