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

如何用xmlstarlet与XPath同时提取XML元素及属性值?

用xmlstarlet同时提取对应XML节点与属性值的方法

XML结构

root
 +- foo
 +- bar
 |   +- @baz

需求

我需要在命令行一次性提取/root/foo的文本值和/root/bar/@baz的属性值,并且让每一组对应的值显示在同一行。

已尝试的命令及问题

有效但拆分的命令

分别执行以下命令可以单独获取对应值,但无法合并为每行一组的格式:

cat file.xml | xmlstarlet sel -t -v "/root/foo" -n

返回结果:

Value F1
Value F2
cat file.xml | xmlstarlet sel -t -v "/root/bar/@baz" -n

返回结果:

Value B1
Value B2

无效命令1

尝试用XPath或表达式合并,但仅返回foo的值:

cat file.xml | xmlstarlet sel -t -v "/root/foo|bar/@baz" -n

返回结果:

Value F1
Value F2

无效命令2

尝试用逻辑表达式筛选,直接编译报错:

cat file.xml | xmlstarlet sel -t -v "/root/[foo and bar/@baz]" -n

报错信息:

compilation error: element with-param
XSLT-with-param: Failed to compile select expression '/root/[foo and bar/@baz]'

更新:最小可复现示例

XML文件内容

<root>
  <foo>Value F1</foo>
  <bar baz="Value B1" />

  <foo>Value F2</foo>
  <bar baz="Value B2" />
</root>

期望输出

Value F1 Value B1
Value F2 Value B2

使用的xmlstarlet版本

1.6.1
compiled against libxml2 2.9.13, linked with 20913
compiled against libxslt 1.1.35, linked with 10135

解决方案

可以通过匹配节点位置的方式,将对应位置的foo和bar/@baz值拼接输出,使用以下命令:

xmlstarlet sel -t -m "/root/foo" -v "." -o " " -v "../bar[position()=current()/position()]/@baz" -n file.xml

或者用concat函数简化:

xmlstarlet sel -t -m "/root/foo" -v "concat(., ' ', ../bar[position()=position()]/@baz)" -n file.xml

命令说明

  • -m "/root/foo":遍历每个foo节点
  • -v ".":输出当前foo节点的文本值
  • -o " ":输出分隔空格
  • -v "../bar[position()=current()/position()]/@baz":输出与当前foo同位置的bar节点的baz属性值
  • -n:每组值输出后换行

执行上述命令后,即可得到期望的每行一组的输出格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 10:42:53