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

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调整实现:

  1. 用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规则。

  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 18:34:51