2016-07-07 3 views
0

Я хотел бы отфильтровать пример ниже xml, используя bash.Получить имя атрибута из xml

Проблема: Если атрибут subnode 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/СЭД/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"? –

0

Использование xmlstarlet:

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

Если вы должны использовать xmllint, то сделать это:

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

Смежные вопросы