XmlLint XPath结果含换行无法脚本解析,如何实现明确分隔?支持HTML
问题:XmlLint XPath查询结果含换行符导致脚本无法解析
使用XmlLint执行XPath查询时,部分结果节点内部包含换行符(如示例中<p>标签内的换行),导致标准Shell脚本无法区分不同节点结果。XmlLint没有类似GNU grep/sed的-z(空字符分隔)参数,需解决如何让其返回可明确分隔的结果,或寻找支持HTML的替代工具。
示例XML文件:
<?xml version="1.0" encoding="UTF-8"?> <root> <p>Hello, world!</p> <i>Hey</i> <p>Bye.</p> </root>
执行xmllint --xpath '//p' example.xml的输出:
<p>Hello, world!</p> <p>Bye.</p>
可见第一个<p>节点内部的换行与节点间的换行无法区分,脚本无法正确拆分结果。
解决方案
一、XmlLint适配方案
XmlLint无内置空字符分隔选项,可通过后续工具或XPath调整实现:
用sed替换节点分隔符为\0
利用节点结束标签后的换行作为分界,将其替换为空字符,便于脚本用read -d ''读取:xmllint --xpath '//p' example.xml | sed -e 's|</p>\n|</p>\x00|g'脚本处理示例:
xmllint --xpath '//p' example.xml | sed -e 's|</p>\n|</p>\x00|g' | while IFS= read -r -d '' node; do # 处理单个节点 echo "当前节点:$node" done注:该方法依赖输出中节点结束标签后有换行,需根据实际输出调整sed规则。
XPath统一去除内部换行
使用normalize-space()函数消除节点内部的换行和多余空格,让每个节点结果变为单行:xmllint --xpath '//p/normalize-space()' example.xml输出:
Hello, world! Bye.此方法仅保留文本内容,丢失原始标签结构,适合仅需提取文本的场景。
二、替代工具
若XmlLint无法满足需求,以下工具支持HTML/XML解析,且可自定义结果分隔符:
1. Xidel
支持XML和HTML,可直接指定输出分隔符:
- 空字符分隔节点输出:
xidel example.xml --xpath '//p' --output-separator '\0' - 换行分隔节点文本:
xidel example.xml --xpath '//p/text()' --output-separator '\n'
2. xmlstarlet
全能XML处理工具,可通过参数添加自定义分隔符:
xmlstarlet sel -t -m '//p' -c . -o $'\0' example.xml
其中-o $'\0'表示在每个节点后输出空字符。
3. pup(HTML专属)
专注HTML解析,支持CSS选择器,可指定分隔符:
cat example.html | pup 'p' --separator '\0'
语法贴近前端选择器,适合HTML场景。
内容的提问来源于stack exchange,提问作者Melab
相关产品推荐
相关产品推荐

