
次のように、改行で区切られた2つのXMLを含むファイルがあります。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><ORDERS05><IDOC><EDI_DC40><TABNAM/><DOCNUM>123456</DOCNUM><DIRECT/><IDOCTYP/><STDMES>ORDRSP</STDMES><SNDPOR>SI_GIS-EDI</SNDPOR><SNDPRT>LS</SNDPRT><SNDPRN>0000929674</SNDPRN><RCVPOR>SAP_PI</RCVPOR><RCVPRN>SAP_PI</RCVPRN><CREDAT>20170905</CREDAT><CRETIM>105630</CRETIM><REFINT>17832651</REFINT><REFMES>1</REFMES></EDI_DC40></IDOC></ORDERS05>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><ORDERS05><IDOC><EDI_DC40><TABNAM/><DOCNUM>12345</DOCNUM><DIRECT/><IDOCTYP/><STDMES>ORDRSP</STDMES><SNDPOR>SI_GIS-EDI</SNDPOR><SNDPRT>LS</SNDPRT><SNDPRN>0000929677</SNDPRN><RCVPOR>SAP_PI</RCVPOR><RCVPRN>SAP_PI</RCVPRN><CREDAT>20170905</CREDAT><CRETIM>105630</CRETIM><REFINT>17832651</REFINT><REFMES>1</REFMES></EDI_DC40></IDOC></ORDERS05>
このタグからDOCNUM、MESTYP、SNDPRNの値を抽出し、各行が「XML」で始まるカンマ区切りファイルとして保存したいと思います。タグが欠落している場合(たとえば、XMLのMESTYP)、コンマで置き換えられます。私の出力は次のとおりです。
XML,123456,,0000929674
XML,12345,,0000929677
次のコードを使用してDOCNUMとSNDPRNの値のみを抽出しようとすると、正常に動作します。
sed 's/.*<DOCNUM>\(.*\)<\/DOCNUM>.*<SNDPRN>\(.*\)<\/SNDPRN>.*/XML,\1,\2/' input.xml >> output.xml
ただし、MESTYPタグがinput.xmlファイルにないため、次のコードでは出力が機能しないようです。
sed 's/.*<DOCNUM>\(.*\)<\/DOCNUM>.*<MESTYP>\(.*\)<\/MESTYP>.*<SNDPRN>\(.*\)<\/SNDPRN>.*/XML,\1,\2\3/' input.xml >> output.xml
上記のコードは、何らかの方法でinput.xmlを変更しないようです。なぜですか?タグ(例:MESTYP)がない場合は、コンマを追加するように上記のコードをどのように変更できますか?
注:XMLlintなどのXMLユーティリティは使用できません。既存のコードを修正したいです。ありがとうございます!
答え1
このタイプのデータを処理するのに適したツールであるXML / HTMLパーサーをインストールする機会を逃さないでください。
現時点では、これはアッ特定の状況に対する回避策:
awk -F'[<>]' '{ for(i=1;i<=NF;i++) { if($i~/DOCNUM|MESTYP|SNDPRN/) a[$i]=$(i+1) }
print "XML",a["DOCNUM"],a["MESTYP"],a["SNDPRN"] }' OFS=',' your.xml
出力:
XML,123456,,0000929674
XML,12345,,0000929677
答え2
while IFS= read -r xmldoc; do
printf '%s\n' "$xmldoc" |
xml sel -t -o 'XML,' \
-v '//DOCNUM' -o ',' \
-v '//MESTYPE' -o ',' \
-v '//SNDPRN' -nl
done <file.xml >output.txt
output.txt
これは次のように生成されます。
XML,123456,,0000929674
XML,12345,,0000929677
入力ファイルの各行を読み、file.xml
次に送信します。XMLスター処理のため。 XMLStarlet呼び出しは、指定されたコンマで区切られたXMLノードを見つけて出力します。