xmlstarlet处理非合规XHTML声明头异常及批量修复bash命令求助
xmlstarlet 出现异常格式的原因
xmlstarlet 调用 --html 参数时使用 libxml2 的 HTML 解析逻辑,该逻辑会把文件原有 XML 声明识别为普通处理指令节点,而非文档层面的XML声明:
- 未加
--omit-decl参数时,xmlstarlet 会先输出自身生成的XML声明,再把原文件的XML声明作为处理指令输出,由于处理指令默认会用<? ... ?>包裹,原声明末尾已自带?>,最终就会出现??>的异常后缀,同时产生两行XML声明。 - 加了
--omit-decl参数后,xmlstarlet 不再输出自身生成的声明,但仍会将原XML声明作为处理指令放在DOCTYPE之后,保留末尾多余的问号。
批量原地修复命令
你可以通过 sed 对 xmlstarlet 的输出做后处理,批量修正所有 .xhtml 文件的头部问题,命令如下:
for xhtml_file in *.xhtml; do xmlstarlet fo --omit-decl --recover --html "$xhtml_file" \ | sed -e '1{h;d}' -e '2{x;G}' -e 's/\(<?xml[^>]*\)\?\?>/\1?>/' \ > "${xhtml_file}.tmp" && mv "${xhtml_file}.tmp" "$xhtml_file" done
命令逻辑说明:
1{h;d};2{x;G}实现交换输出内容的第一行(DOCTYPE)和第二行(XML声明)的位置s/\(<?xml[^>]*\)\?\?>/\1?>/匹配并删除XML声明末尾多余的问号,修复??>格式错误- 临时文件中转后覆盖原文件,避免处理过程中损坏原始文件
更适配的替代方案
针对XHTML标签闭合的需求,直接使用 tidy 工具更为合适,它是专门为HTML/XHTML语法修复设计的工具,不会出现XML声明异常问题,直接批量原地修正的命令如下:
tidy -q -asxhtml -m --encoding utf8 --show-warnings no *.xhtml
执行后会自动修正所有空标签的闭合格式,同时保留原有XML声明和DOCTYPE的位置、属性。
内容的提问来源于stack exchange,提问作者minto
相关产品推荐
相关产品推荐

