仅提取 XML 文件中设置的值的最简单方法是什么?例如XML文件中的数据是
<node name="host">
<map>
<entry key="cipher_strength" value="low" />
<entry key="port" value="78234" />
<entry key="over_ssl" value="false" />
<entry key="using_fips" value="true" />
<entry key="ssl_keystore" value="lib/ssl" />
</map>
</node>
我只想low
从脚本中显示。
这是sed
我正在使用的命令,它返回完整的字符串
sed -n '/cipher_strength/{s/.*<cipher_strength>//;s/<\/cipher_strength.*Value=""//;p;}' test.xml
根据评论,我无法使用,xmlstarlet
因为这在我的 suse 版本上不可用,并且已被供应商锁定,因此无法安装。
答案1
使用命令行 XML 解析器xmlstarlet
:
xmlstarlet sel -t -v '//entry[@key="cipher_strength"]/@value' -nl file.xml
这将匹配entry
XML 文档中任何位置的所有节点,并且value
如果同一entry
节点具有key
值为 的属性,则将提取其属性的值cipher_strength
。每个值都将输出一个尾随换行符。
xmllint
各种系统上可用的实现似乎在对执行 XPath 查询的支持方面有所不同。
在我的 OpenBSD 系统上,你可以这样做
xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml
去取回
value="low"
然而,xmllint --xpath '//entry[@key="cipher_strength"]/@value/text()' file.xml
我本以为会给我字符串low
,但它似乎不起作用(只是生成XPath set is empty
响应)。
只要value
属性的值是“nice”,您就应该能够处理此输出以提取实际值:
$ xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml | sed -e 's/^[^"]*"//' -e 's/"$//'
low
上面的表达式sed
从每行删除第一个双引号字符之前的所有内容,然后还截掉最后一个双引号字符。
其他xmllint
实现/版本可能已经采用了以下方法xmllint --shell
:
xmllint --shell file.xml <<<'cat //entry[@key="cipher_strength"]/@value' |
sed -e '/^[^ ]/d' -e 's/^[^"]*"//' -e 's/"$//'
答案2
如果没有专用的 XML 工具可用,您可能想尝试使用awk
:调用
user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
将查找包含所有以空格分隔的字符串的行key="cipher_strength"
,然后在符号处拆分所有空格分隔的字符串=
。对于所有包含“中间”该符号的符号(即前面有一个部分,后面有一个部分),检查第一部分是否等于value
,如果等于则打印第二部分。对于您的输入,我得到
user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
"low"
如果有更多<node>
节点,您可以尝试修改程序以确保在应用此操作之前处于正确的位置。