xmllint仅选中首个<id>元素,如何提取所有<id>文本到文件
解决xmllint提取所有元素文本的问题
我明白你遇到的困扰了——直接用xmllint test.xml --xpath "string(//id)"只会返回第一个匹配的<id>内容,这是因为XPath的string()函数仅会处理节点集中的第一个节点。下面给你几个可行的方案,都能实现把每个<id>的文本单独提取到一行:
方案1:结合xmllint的shell模式与过滤工具
xmllint的--shell模式可以交互式执行XPath查询,我们可以用它遍历所有<id>节点,再用awk过滤出文本内容:
xmllint --shell test.xml <<EOF | awk '/text/{print \$NF}' xpath //id EOF
执行后每个<id>的内容就会单独占一行输出,你可以直接把结果重定向到文件:
xmllint --shell test.xml <<EOF | awk '/text/{print \$NF}' > ids.txt xpath //id EOF
方案2:查询所有文本节点后拆分输出
如果你的xmllint版本查询//id/text()时会把所有文本连在一起输出(比如111222333),可以结合grep和正则表达式拆分(假设ID为数字,可根据实际内容调整正则):
xmllint --xpath '//id/text()' test.xml | grep -o '[0-9]\+' > ids.txt
要是ID包含字母或特殊字符,把正则改成grep -o '[A-Za-z0-9_-]\+'这类匹配规则即可。
方案3:逐个定位节点提取(精准可控)
如果你想纯靠XPath逻辑实现,可以先获取<id>节点的总数,再循环逐个提取并手动换行:
count=$(xmllint --xpath 'count(//id)' test.xml) for i in $(seq 1 $count); do xmllint --xpath "//id[$i]/text()" test.xml echo done > ids.txt
这个方法能精准定位每个<id>节点,确保每个ID单独占一行输出。
小提示
如果你的XML带有命名空间,记得在XPath里加上对应前缀(比如//rss:item/rss:id),并通过xmllint的命名空间参数指定映射,否则可能无法匹配到目标节点。
内容的提问来源于stack exchange,提问作者Aleksandar
相关产品推荐
相关产品推荐

