如何使用xmllint/xpath解析不同元素上几个属性的值?
对于一个名为configurations.xml的给定xml文件,我想提取每个如何使用xmllint/xpath解析不同元素上几个属性的值?,xml,bash,xpath,Xml,Bash,Xpath,对于一个名为configurations.xml的给定xml文件,我想提取每个conf元素的值,并将其存储在一个变量中供以后使用 <configurations> <conf name="bob"/> <conf name="alice"/> <conf name="ted"/> <conf name="carol"/> </configurations> 我有xpath和xmllint可用。//conf/
conf
元素的值,并将其存储在一个变量中供以后使用
<configurations>
<conf name="bob"/>
<conf name="alice"/>
<conf name="ted"/>
<conf name="carol"/>
</configurations>
我有xpath和xmllint可用。
//conf/@name
的xpath获取节点,但输出为name=“bob”
,这正是我试图避免的。可以使用awk
命令来完成
[root@myserver tmp]# cat /tmp/test.xml
<configurations>
<conf name="bob"/>
<conf name="alice"/>
<conf name="ted"/>
<conf name="carol"/>
</configurations>
[root@myserver tmp]# awk -F \" '{print $2}' /tmp/test.xml |grep -v '^$'
bob
alice
ted
carol
[root@myserver tmp]#
[root@myservertmp]#cat/tmp/test.xml
[root@myservertmp]#awk-F \“{print$2}'/tmp/test.xml | grep-v'^$”
上下快速移动
爱丽丝
特德
颂歌
[root@myserver[tmp]#
我不知道如何仅用xmllint
就能实现您想要实现的目标
由于安装了xpath
,因此也安装了Perl的XML::xpath
#!/usr/bin/perl
use XML::Path;
my $xp=XML::XPath->new(filename => 'configurations.xml');
my $nodeset=$xp->find('//conf/@name');
foreach my $node ($nodeset->get_nodelist) {
print $node->getNodeValue,"\0";
}
将输出所需内容,以零字符分隔
在一行样式中:
perl -mXML::XPath -e 'foreach $n (XML::XPath->new(filename => "configurations.xml")->find("//conf/\@name")->get_nodelist) { print $n->getNodeValue,"\0"; }'
要在例如Bash数组中检索它们,请执行以下操作:
#!/bin/bash
names=()
while IFS= read -r -d '' n; do
names+=( "$n" )
done < <(
perl -mXML::XPath -e 'foreach $n (XML::XPath->new(filename => "configurations.xml")->find("//conf/\@name")->get_nodelist) { print $n->getNodeValue,"\0" }'
)
# See what's in your array:
display -p names
!/bin/bash
名称=()
而IFS=read-r-d''n;do
名称+=(“$n”)
完成<如果您真的想使用xpath
并且只显示属性值而不显示“name=”部分,那么下面是对我有效的方法:
xpath configurations.xml 'string(//conf/@name)' 2>/dev/null
用简单的英语,将XPath查询包装在string()
中,并通过在末尾添加2>/dev/null
来抑制XPath
的详细输出
xmlstarlet sel -t -m '//configurations/conf' -v '@name' -n a.xml
因为xmllint
似乎没有能力工作。介绍得不错
测试版本:xmlstarlet版本1.5.0,Ubuntu 14.04
但是,它在大文件上失败:ulimit-Sv 500000
(将其限制为500Mb)在1.2Gb XML上死亡,并在没有内存限制的情况下阻塞我的计算机。另请参阅:
我到处搜索这个看似简单的答案。似乎xmllint
不可能从多个节点打印属性值。您可以使用字符串(//conf/@name)
,但即使有多个匹配的节点,也只能打印单个值
如果您一直使用xmllint
,唯一的方法就是使用额外的文本处理。下面是一种解析属性值的通用方法。它假定值不包含=
或“
字符
xmllint --xpath //conf/@name |
tr ' ' '\n' | awk -F= '{print $2}' | sed 's/"//g'
第一条管道将空间转换为换行线
第二个管道打印=
最后一个管道删除了所有“
我需要它是一个更具体的匹配,而不仅仅是从开始的所有内容”。XML文档中还有其他我不想匹配的元素。因此,在这种情况下,您只需要conf name
?我主要考虑的是在纯bash中是否可能。但我想这最终没有意义。这在libxml版本20901 Ubuntu 14.04上对我不起作用:它只在使用string()
时打印第一个值。你是对的,我只测试了一个子节点。我会保持答案不变,也许它对0.1%有这个问题的人有用。
xmllint --xpath //conf/@name |
tr ' ' '\n' | awk -F= '{print $2}' | sed 's/"//g'