我有下面的HTML代码:
<textarea name="command" class="setting-input fixed-width" rows="9">1</textarea><textarea name="command" class="setting-input fixed-width" rows="5">2</textarea>
我想解析它以接收这样的输出:
1
2
目前我正在使用:
xmllint --xpath '//textarea[@name="command"]/text()' --html
但是它不在每个匹配后附加换行符。
5条答案
按热度按时间dfuffjeb1#
来自2020年的你好!
从libxml的v2.9.9开始,此行为has been fixed in
xmllint
itself.然而,如果你使用的是比这更老的版本,并且不想从源代码构建libxml来获得修复的
xmllint
,那么你需要其他的解决方法之一。例如,在撰写本文时,最新的CentOS 8仍然使用的是OP描述的libxml版本(2.9.7)。我从this SO answer中了解到,从理论上讲,可以将一个命令输入到旧版本的
--shell
选项中(〈2.9.9)版本的xmllint
,这将在单独的行上生成每个节点。最后不得不使用sed
或grep
对其进行后处理,以去除shell模式(面向人的)输出中的视觉碎片,这并不理想。XMLStarlet(如果可用)提供了另一种解决方案,但是在使用
xmlstarlet sel
提取节点之前,您确实需要使用xmlstarlet fo
将HTML片段格式化为有效的XML:如果来自第二个
xmlstarlet
调用的Attempt to load network entity
消息令您烦恼,只需在最后添加2>/dev/null
以抑制它(有可能抑制打印到标准错误的其他消息)。XMLStarlet选项说明(另请参见user's guide):
fo -H -R
-format输出,预期HTML输入,并尽可能多地恢复错误输入<html>
根节点,使OP示例中的片段成为有效的XMLsel -T -t -v //xpath -n
-选择基于XPath//xpath
的节点-T
)而不是XML-t
)返回节点的值(-v
),而不是节点本身(允许您放弃在XPath表达式中使用text()
)-n
)编辑:删除了实现了一半的
xmllint --shell
解决方案,因为它很糟糕。添加了一个XMLStarlet示例,它实际上可以处理OP的数据。3vpjnl9f2#
尝试this patch,它提供2个选项:
--xpath
:与旧的--xpath
相同,节点之间用\n
分隔。--xpath0
:与旧的--xpath
相同,节点之间用\0
分隔。测试输入(
a.html
):测试命令1:
测试输出1:
测试命令2:
测试输出2:
ugmeyewa3#
我做了以下,丑陋的伎俩,请随时提供一个更好的解决方案。
通过使用以下命令将
</textarea>
替换为\n</textarea>
,更改了HTML代码:7tofc5zh4#
下面是一个 Package 器脚本,完全用于换行符分隔的输出(对于
xmllint
的旧版本)。创建一个包含内容的文件
xmllint2.sh
,然后执行chmod u+x xmllint2.sh
,最后像这样运行:./xmllint2.sh --xpath --html '//textarea[@name="command"]/text()' 2>/dev/null
(the命令的最后一部分是隐藏使用html发生的警告的输出)
检查最新版本:https://github.com/sputnick-dev/xmllint
Debian Buster于2020年6月29日发布了2.9.4版本,已经4年了。
Debian测试/实验版有2.9.10,这是修复版本。
另一种用Debian最新稳定版安装2.9.10的方法:https://serverfault.com/a/1022826/120473(无需承担
apt
系统崩溃的风险)i1icjdpr5#
换行符可以合法地出现在XML数据中。一个更健壮的方法是用一个保证不会出现在XML数据中的字符来分隔xpath结果。Null character,即Universal Coded Character Set中的U +0000,就是这样一个字符。
注意,赋给空控制字符的代码点U +0000是唯一一个以Unicode和ISO/IEC 10646编码的字符,它在任何XML 1.0和1.1文档中总是无效的。
@Cyker的merge request for
xmllint
包括添加了一个-xpath0
选项,该选项将通过NUL分隔xpath结果。用于此功能的A new feature request也已打开。希望
xmllint
很快就能获得这个特性。xml小星星
与此同时,另一个xpath命令行工具
xmlstarlet
现在也可以实现这一目标。xmlstarlet
目前不直接支持NUL的输出,但是我们可以让它输出U+FFFF
,与NUL一样,XML数据(源代码)中不会出现,我们只需要将U+FFFF
转换为U+0000
,得到的xpath结果为NUL分隔。在下面的例子中,我将使用下面的部分html文件。它与OP的问题中的例子相同,除了我添加了换行符用于测试目的。
下面是如何使用
xmlstarlet
和sed
来用NULL分隔xpath结果:如果您愿意,可以使用
perl
代替sed
:perl -CS -0xFFFF -l0 -pe ''
注意:我通过
xmlstarlet fo -H -R
运行HTML,如@TheDudeAbides答案所示。现在xpath结果由NULL分隔,我们可以在
xargs -0
的帮助下处理结果。结果:
或者将其加载到bash数组中:
结果:
撒克逊人
使用saxon而不是xmlstarlet的相同技术: