如何使用xmllint / xpath解析不同元素上的几个属性的值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用xmllint / xpath解析不同元素上的几个属性的值?相关的知识,希望对你有一定的参考价值。

对于名为configurations.xml的给定xml文件,我想提取每个conf元素的值,并将其存储在变量中供以后使用。

<configurations>
  <conf name="bob"/>
  <conf name="alice"/>
  <conf name="ted"/>
  <conf name="carol"/>
</configurations>

预期的产出是:

bob
ailce
ted
carol

我有xpath和xmllint可用。 //conf/@name的xpath获取节点,但输出为name="bob",这是我想要避免的。

答案

我不知道如何实现你只想用xmllint实现的目标。

既然你安装了xpath,那么你也有Perl的XML::XPath。那么一点点Perl:

#!/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,"";
}

将输出你想要的,用零字符分隔。

采用单线式:

perl -mXML::XPath -e 'foreach $n (XML::XPath->new(filename => "configurations.xml")->find("//conf/@name")->get_nodelist) { print $n->getNodeValue,""; }'

要在例如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,"" }'
)
# See what's in your array:
display -p names

请注意,此时您可以选择转到Perl并完全删除Bash以解决您的问题。

另一答案
xmlstarlet sel -t -m '//configurations/conf' -v '@name' -n a.xml

自从xmllint似乎没有能力。好介绍here

测试:xmlstarlet版本1.5.0,Ubuntu 14.04。

但它在大文件上失败:ulimit -Sv 500000(限制为500Mb)在1.2Gb XML上死机,并且在没有内存限制的情况下阻塞我的计算机。也可以看看:

另一答案

如果你真的想使用xpath并且只显示没有“name =”部分的属性值,那么这里对我有用:

xpath configurations.xml 'string(//conf/@name)' 2>/dev/null

用简单的英语,将你的XPath查询包装在string()中,并通过在末尾添加xpath来抑制2>/dev/null的详细输出。

另一答案

我到处寻找这个看似简单的答案。看来xmllint不可能从多个节点打印属性值。您可以使用string(//conf/@name),但即使有多个匹配的节点,也只会打印单个值。

如果你坚持使用xmllint,唯一的方法是使用额外的文本处理。这是一种解析属性值的通用方法。它假定值不包含="字符。

xmllint --xpath //conf/@name | 
tr ' ' '
' | awk -F= '{print $2}' | sed 's/"//g'

第一个管道将空格转换为换行符。

第二个管道打印出=之后的内容

最后一个管道删除所有"

另一答案

您可以使用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]#

以上是关于如何使用xmllint / xpath解析不同元素上的几个属性的值?的主要内容,如果未能解决你的问题,请参考以下文章

没有 --xpath 选项的 xmllint 字符串

使用xmllint从XML节点获取URL,添加新行

使用 xpath 或 css 选择器解析混合移动应用程序中的所有元素

无法使用 xpath 解析来自某些 html 元素的某些信息

xmllint:如何使用本地 DTD 文件验证 XML

如何在 Sublime Text 3 中使用 xmllint?