2009-05-26 1 views
3

Ich habe eine XML-Datei mit folgendem Datenformat:Wie kann ich ein XML-Dokument mit awk, Perl oder Python extrahieren?

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

Kann mir jemand sagen, wie ich Daten, die die XML-Datei mit einem awk Einzeiler Mine könnten? Zum Beispiel möchte ich attr3 von abc wissen. Es wird mir 345 zurückgeben.

+0

versuchen, dich nicht zu schreien, aber wenn Sie eine Frage stellen, können Sie auf der rechten Seite sehen, und es wird Ihnen eine schöne Formatierung Führung zeigen, so dass Ihr Code gut aussehen und hervorgehoben werden. –

+2

Vergessen Sie awk für solche "reiche" und komplexe Aufgaben - Perl ist wirklich entworfen, um alle awk tun können, nur besser (und wenn Sie in neueren Sprachen wie Ruby oder Python scharf sind, sind sie auch in Ordnung, aber Perl ist näher an awk entlang vieler Achsen). –

+1

XPath: // net [@ NetName = "abc"]/attribut :: attr3 gibt 345 zurück – bernie

Antwort

7

Im Allgemeinen you don't. XML/HTML-Parsing ist schwer genug, ohne es präzise zu machen, und während Sie vielleicht in der Lage sind, eine Lösung zu hacken, die mit einer begrenzten Teilmenge von XML Erfolg hat, wird sie irgendwann brechen.

Außerdem, there are many great languages with great XML parsers already written, warum also nicht einen von ihnen verwenden und Ihr Leben einfacher machen?

Ich weiß nicht, ob es einen XML-Parser für awk gibt oder nicht, aber ich fürchte, wenn Sie XML mit awk analysieren wollen, werden Sie viele "Hämmer sind für Nägel, Schraubenzieher sind für Schrauben "Antworten. Ich bin mir sicher, dass es möglich ist, aber es wird Ihnen wahrscheinlich leichter fallen, in Perl etwas zu schreiben, das XML :: Simple (mein persönlicher Favorit) oder ein anderes XML-Parsing-Modul verwendet.

Nur der Vollständigkeit halber möchte ich darauf hinweisen, dass es sich bei ungültigem XML-Code nicht um ein gültiges Beispiel für die gesamte Datei handelt. Gültige XML sollten Start- und End-Tags haben, etwa so:

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

Ich bin sicher, dass ungültige XML seine Verwendung hat, aber einige XML-Parser darüber jammern kann, so dass, wenn Sie sich mit einem awk ein Toter Satz sind -liner versuchen, Ihr "XML" zu analysieren, sollten Sie in Betracht ziehen, Ihr XML gültig zu machen.

Als Antwort auf Ihre Bearbeitungen, ich werde tun es immer noch nicht als Einzeiler, aber hier ist ein Perl-Skript, das Sie verwenden können:

mit 1
#!/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(); 
} 

Führen Sie dieses Skript von der Kommandozeile oder 2 Argumente. Das erste Argument ist 'NetName', das Sie suchen möchten, und das zweite ist das Attribut, das Sie suchen möchten. Wenn kein Attribut angegeben wird, sollte es nur alle Attribute für dieses 'NetName' auflisten.

+0

mein schlechtes ich vergesse, das komplette Dateiformat –

+0

einzufügen Es ist cool. Ich habe nur überprüft, ob der von Ihnen gepostete Code nur ein Ausschnitt ist und nicht Ihre vollständige Datei. –

+0

ich könnte die schwierigkeit von diesem unterschätzt werden, wie ich, obwohl es im Einliner getan werden könnte ... :) –

7

Ich habe ein Werkzeug mit der Bezeichnung xml_grep2, basierend auf XML::LibXML, die Perl-Schnittstelle zu libxml2 geschrieben.

Sie würden den Wert finden Sie suchen, indem Sie diese:

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

Das Werkzeug kann bei http://xmltwig.com/tool/

+0

Das ist schön. Ich werde es mir ansehen. –

5

xmlgawk gefunden werden kann sehr leicht XML verwenden.

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

Dieser eine Liner kann XML analysieren und "345" drucken.

+0

Das sieht ziemlich gut aus. –

+0

das ist toll ... aber schade, dass meine Firma Linux xmlgawk nicht installiert –

2

Wenn Sie nicht xmlgawk haben und Ihr XML-Format ist behoben, kann normal awk tun.

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

Dieses Skript kann "345" zurückgeben. Aber ich denke, es ist sehr gefährlich, weil normale awk XML nicht verwenden kann.

Verwandte Themen