2016-07-07 190 views
0

我想使用bash过滤example-below xml。从xml获取属性名称

问题: 如果子节点att =“t”的属性存在,则应该打印属性名称。

输入:

<?xml version="1.0" encoding="UTF-8"?> 
<general> 
    <node1> 
     <subnode att1="a" att2="t" name="test"> </subnode> 
     <subnode att1="a" name="test2"> </subnode> 
     <subnode att1="a" name="test3"> </subnode> 
     <subnode att1="a" att2="t" name="test4"> </subnode> 
    </node1> 
</general> 

输出:

test 
test4 

我试图grep和xmllint,但没有成功。

我的 “临时” 的解决方案是:

xmllint --xpath 'string(//general/node1/subnode[@att2="t"]/@name)' file.xml 

但该命令只打印第一次出现 - 测试。

回答

0

不是你问的相当的东西,但用perl(和XML解析器)应该是你的系统上容易获得这两个:(比如他们都应该通过包管理器可以在大多数发行版 - XML::Twig也可以通过cpan下载如果你喜欢)

#!/usr/bin/env perl 
use strict; 
use warnings; 
use XML::Twig; 

my $twig = XML::Twig->parse(\*DATA); 

print $_->att('name'),"\n" for $twig->get_xpath('//subnode[@att2="t"]'); 

__DATA__ 
<?xml version="1.0" encoding="UTF-8"?> 
<general> 
    <node1> 
     <subnode att1="a" att2="t" name="test"> </subnode> 
     <subnode att1="a" name="test2"> </subnode> 
     <subnode att1="a" name="test3"> </subnode> 
     <subnode att1="a" att2="t" name="test4"> </subnode> 
    </node1> 
</general> 

作为一个衬垫,这成为:

perl -0777 -MXML::Twig -e 'print $_->att("name"),"\n" for XML::Twig->parse(<>)->get_xpath(q{//subnode[@att2="t"]})' 

这一个衬垫可以在同样的方式AWK/SED/grep的如使用作为管道xml的地方,或者用命令行指定的文件。

0

请检查,如果这个工程

awk '{if(/att[0-9]="t"/){line=$0;replacedLine=substr(line,index(line,"name="));gsub(/name="/,"",replacedLine);endIndex=index(replacedLine,"\"");print substr(replacedLine,0,endIndex);}}' xmlfile 
+0

不工作,有时打印其他属性。 – profiler

+0

我需要非工作案例的XML内容,以便我可以修复。请更新您的问题更少的情况下。另外,我的代码假设你想匹配包含att [any_number] =“t”的行。不是吗?你只需要匹配att2 =“t”? – 2016-07-07 12:06:59

0

使用xmlstarlet:如果你必须使用xmllint

xmlstarlet sel -t -v '//general/node1/subnode[@att2="t"]/@name' -nl 

,那么这样做:

xmllint --xpath '//general/node1/subnode[@att2="t"]/@name' sample.xml \ 
    | sed 's/ name="//g; s/"/\n/g;' 
+0

xmlstarlet不是标准命令......最好的解决方案是使用xmllint。 – profiler

+1

你的意思是它不在你的**系统上。 –

+0

是的,确实如此。我想使用那个命令哪一个在linux上。 – profiler