2016-07-05 4 views
0

Meine Eingabe XML ist unten. Ich muss in meiner XML-Eingabe suchen, wenn das Schlüsselwort "SEARCH" vorhanden ist. Wenn vorhanden, muss ich den Inhalt von <record> zu </record> kopieren und in eine andere XML-Datei schreiben.awk: Suche nach einem Schlüsselwort in XML und schreibe in eine andere Datei

XML-Input-

<XML> 
<record category="xyz"> 
<person ssn="" e-i="E"> 
<title xsi:nil="true"/> 
<position xsi:nil="true"/> 
<details> 
<names> 
<first_name/> 
<last_name></last_name> 
</names> 
<aliases> 
<alias>CDP</alias> 
</aliases> 
<keywords> 
<keyword xsi:nil="true"/> 
<keyword>SEARCH</keyword> 
</keywords> 
<external_sources> 
<uri>http://www.google.com</uri> 
<detail>SEARCH is present in abc for xyz reason</detail> 
</external_sources> 
</details> 
</person> 
</record> 
<record category="abc"> 
<person ssn="" e-i="F"> 
<title xsi:nil="true"/> 
<position xsi:nil="true"/> 
<details> 
<names> 
<first_name/> 
<last_name></last_name> 
</names> 
<aliases> 
<alias>CDP</alias> 
</aliases> 
<keywords> 
<keyword xsi:nil="true"/> 
<keyword>DONTSEARCH</keyword> 
</keywords> 
<external_sources> 
<uri>http://www.google.com</uri> 
<detail>SEARCH is not present in abc for xyz reason</detail> 
</external_sources> 
</details> 
</person> 
</record> 
</XML> 

Mein jetziger Code:

NR==FNR { 
keywordArray[NR]=$0; 
next; 
} 

/<record/{ i=1 } 
i { a[i++]=$0 } 
/<\/record>/ { 
    if (found) { 
     for (i=1; i<=length(a); ++i) print a[i] >> output.xml 
    } 
    i=0; 
    found=0 
} 
$0 ~ "<keyword>"SEARCH"</keyword>" { found=1 } 

Ausgabe mit aktuellem Code:

Der Code nicht für "SEARCH", und es ist auf der Suche schreibt nichts in output.xml

Erwartete Ausgabe:

<record category="xyz"> 
<person ssn="" e-i="E"> 
<title xsi:nil="true"/> 
<position xsi:nil="true"/> 
<details> 
<names> 
<first_name/> 
<last_name></last_name> 
</names> 
<aliases> 
<alias>CDP</alias> 
</aliases> 
<keywords> 
<keyword xsi:nil="true"/> 
<keyword>SEARCH</keyword> 
</keywords> 
<external_sources> 
<uri>http://www.google.com</uri> 
<detail>SEARCH is present in abc for xyz reason</detail> 
</external_sources> 
</details> 
</person> 
</record> 
+3

Auf Tipp: Manipulieren Sie keine XML-Daten mit zeilenorientierten Werkzeugen wie 'awk'. Verwenden Sie stattdessen XML-fähige Tools wie 'xsltproc' und' xmlstarlet'. –

+0

dh xmlstarlet sel -t -m 'XML/Datensatz/Person/Details/Schlüsselwörter/Schlüsselwort [. = "SEARCH"]' -c '../../../ ..' foo.xml> bar.xml – tomc

+0

@tomc: Warum ist ''../../../ ..'' im obigen Code erforderlich? – user2488578

Antwort

1

Nun, es ist nicht perfekt, aber vielleicht können Sie diese verbessern:

BEGIN { 
    FS="\n"  # field separator to enter 
    OFS="\n"  # output separator as well 
    RS="</record>" # records end at </record> 
} 
$0 ~ /<keyword>SEARCH<\/keyword>/'  # print record if SEARCH matched 
1

Mit xmlstarlet, könnten Sie verwenden:

xmlstarlet sel -t -c "//record[.//keyword/text()='SEARCH']" foo.xml 
+0

@ user2488578 als @Michael Vehrs notierte das '../../../ ..' in meiner (absichtlich expliziten) Version ist '-c'kopieren Sie die Xml-Strophe vier Eltern oben, wo" SEARCH "ist -m 'Atched. – tomc

Verwandte Themen