读取 XML 并仅提取值

读取 XML 并仅提取值

仅提取 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

这将匹配entryXML 文档中任何位置的所有节点,并且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>节点,您可以尝试修改程序以确保在应用此操作之前处于正确的位置。

相关内容