如何在Windows环境下用XmlStarlet根据part1动态值获取对应text元素?
用XmlStarlet根据XML中part1的动态值匹配part2对应的text元素(Windows环境)
需求:根据XML中<part1>节点下<line>的val属性值,获取<part2>中对应val的<line>节点下的<text>内容。比如示例XML中,需要返回2,Text 2和5,Text 5。
示例XML文件(example.xml)
<root> <part1> <line val="2"></line> <line val="5"></line> </part1> <part2> <line val="1"> <text>Text 1</text> </line> <line val="2"> <text>Text 2</text> </line> <line val="3"> <text>Text 3</text> </line> <line val="4"> <text>Text 4</text> </line> <line val="5"> <text>Text 5</text> </line> <line val="6"> <text>Text 6</text> </line> </part2> </root>
错误尝试过程
- 首次尝试用固定值匹配,结果全部返回Text 3:
xml sel -t -m //part1/line -v @val -o "," -c ../../part2/line[@val='3']/text -n example.xml
输出:
2,<text>Text 3</text> 5,<text>Text 3</text>
- 尝试用
concat拼接XPath路径,结果返回路径字符串而非内容:
xml sel -t -m //part1/line -v @val -o "," -c concat('../../part2/line[@val=',@val,']/text') -n example.xml
输出:
2,../../part2/line[@val=2]/text 5,../../part2/line[@val=5]/text
更简便的单条XmlStarlet命令
利用XPath的current()函数引用当前节点的属性值,直接完成动态匹配:
xml sel -t -m "//part1/line" -v "@val" -o "," -v "//part2/line[@val=current()/@val]/text" -n example.xml
输出结果:
2,Text 2 5,Text 5
命令说明:
-m "//part1/line":遍历<part1>下所有<line>节点-v "@val":输出当前<line>的val属性值-o ",":添加逗号分隔符-v "//part2/line[@val=current()/@val]/text":匹配<part2>中val与当前<part1>/line的val相等的<line>节点,并输出其下<text>的内容-n:每条结果后换行
你当前使用的循环方案
虽然可行但需要多次调用XmlStarlet,效率稍低:
for /f "usebackq tokens=*" %f in (`xml sel -t -m //part1/line -v @val -n example.xml`) do @xml sel -t -m //part2/line[@val=%f]/text -v "%f" -o "," -v . -n example.xml
内容的提问来源于stack exchange,提问作者Luuk
相关产品推荐
相关产品推荐

