Как я могу получить документ XML с помощью awk, Perl или Python? - PullRequest
3 голосов
/ 26 мая 2009

У меня есть XML-файл со следующим форматом данных:

<net NetName="abc" attr1="123" attr2="234" attr3="345".../>
<net NetName="cde" attr1="456" attr2="567" attr3="678".../>
....

Может кто-нибудь сказать мне, как я могу добывать данные XML-файла, используя одну строчку awk? Например, я хотел бы знать attr3 из abc. Мне вернутся 345.

Ответы [ 5 ]

7 голосов
/ 26 мая 2009

Я написал инструмент под названием xml_grep2, основанный на XML :: LibXML , интерфейс Perl для libxml2 .

Вы найдете искомое значение, выполнив следующее:

xml_grep2 -t '//net[@NetName="abc"]/@attr3' to_grep.xml

Инструмент можно найти по адресу http://xmltwig.com/tool/

7 голосов
/ 26 мая 2009

В общем, вы не . Синтаксический анализ XML / HTML достаточно сложен, если вы не пытаетесь сделать это кратко, и, хотя вы сможете взломать решение, которое успешно работает с ограниченным подмножеством XML, в конечном итоге оно сломается.

Кроме того, есть много замечательных языков с отличными синтаксическими анализаторами XML, уже написанными , так почему бы не использовать один из них и сделать вашу жизнь проще?

Я не знаю, есть ли парсер XML, созданный для awk, но я боюсь, что если вы захотите проанализировать XML с помощью awk, вы получите много "молотков для гвоздей, отвертки для винтов "ответы. Я уверен, что это можно сделать, но вам, вероятно, будет проще написать что-нибудь быстрое в Perl, использующее XML :: Simple (мой личный фаворит) или какой-то другой модуль XML-разбора.

Просто для полноты я хотел бы отметить, что если ваш фрагмент является примером всего файла, он не является допустимым XML. В допустимом XML должны быть начальные и конечные теги, например:

<netlist>
  <net NetName="abc" attr1="123" attr2="234" attr3="345".../>
  <net NetName="cde" attr1="456" attr2="567" attr3="678".../>
  ....
</netlist>

Я уверен, что недопустимый XML имеет свое применение, но некоторые парсеры XML могут скулить по этому поводу, поэтому, если вы не устали использовать однострочник awk, чтобы попытаться наполовину «разобрать» ваш «XML» возможно, вы захотите сделать свой XML действительным.

В ответ на ваши правки я все равно не буду делать это как однострочник, но вот сценарий Perl, который вы можете использовать:

#!/usr/bin/perl

use strict;
use warnings;
use XML::Simple;

sub usage {
  die "Usage: $0 [NetName] ([attr])\n";
}

my $file = XMLin("file.xml", KeyAttr => { net => 'NetName' });

usage() if @ARGV == 0;

exists $file->{net}{$ARGV[0]}
  or die "$ARGV[0] does not exist.\n";


if(@ARGV == 2) {
  exists $file->{net}{$ARGV[0]}{$ARGV[1]}
    or die "NetName $ARGV[0] does not have attribute $ARGV[1].\n";
  print "$file->{net}{$ARGV[0]}{$ARGV[1]}.\n";

} elsif(@ARGV == 1) {
  print "$ARGV[0]:\n";
  print "  $_ = $file->{net}{$ARGV[0]}{$_}\n"
    for keys %{ $file->{net}{$ARGV[0]} };

} else {
  usage();
}

Запустите этот скрипт из командной строки с 1 или 2 аргументами. Первый аргумент - это 'NetName', который вы хотите найти, а второй - это атрибут, который вы хотите найти. Если атрибут не указан, он должен просто перечислить все атрибуты для этого 'NetName'.

5 голосов
/ 26 мая 2009

xmlgawk может очень легко использовать XML.

$ xgawk -lxml 'XMLATTR["NetName"]=="abc"{print XMLATTR["attr3"]}' test.xml

Этот лайнер может анализировать XML и печатать "345".

2 голосов
/ 26 мая 2009

Если у вас нет xmlgawk, а ваш формат XML фиксированный, обычный awk может сделать.

$ nawk -F '[ ="]+' '/abc/{for(i=1;i<=NF;i++){if($i=="attr3"){print $(i+1)}}}' test.xml

Этот скрипт может возвращать "345". Но я думаю, что это очень опасно, потому что обычный awk не может использовать XML.

0 голосов
/ 29 октября 2013

Вы можете попробовать этот изящный маленький скрипт: http://awk.info/?doc/tools/xmlparse.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...