web-dev-qa-db-ja.com

XMLSTARLETを使用してマルチレベルxmlをすべてのレベルを含む単一行に変換する方法

サンプルXMLは次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
  <level01>
    <field01>AAAAAAAAAAAAAAAAAAAA</field01>
    <field02>BBBBBBBB</field02>
    <field03>CCCCCCCCCCCCCCCCCCCC</field03>
    <field04>DDDDDDDDDDDDDDDDDDDD</field04>
    <field05>DDD</field05>
    <level02>
      <field01>EEEEEEEEE</field01>
      <field02>FFF</field02>
      <field04>GGGGGGGGGGs</field04>
      <field05>HHH</field05>
      <level03>
        <field01>IIIIIIIII</field01>
        <field02>JJJ</field02>
        <field04>KKKKKKKKK</field04>
        <field05>L</field05>
      </level03>
    </level02>
  </level01>
</root>

目的の出力は次のようになります。

AAAAAA,BBBBB, CCCCCCCCCCCCC ,DDDDDDDDDD ,DDD,EEE,FFF,GGGG,HHH,III,JJJ,KKK,L
1
sdfsdf

xml2starletの代わりに xml2 (debianおよび他のほとんどのディストリビューションでパッケージ化されています)をawkおよびpasteとともに使用します。

$ xml2 <sdfsdf.xml | awk -F= '{ print $2 }' | paste -sd,
AAAAAAAAAAAAAAAAAAAA,BBBBBBBB,CCCCCCCCCCCCCCCCCCCC,DDDDDDDDDDDDDDDDDDDD,DDD,EEEEEEEEE,FFF,GGGGGGGGGGs,HHH,IIIIIIIII,JJJ,KKKKKKKKK,L

各カンマの後にスペースが必要な場合は、sedでスペースを追加します。

xml2 <sdfsdf.xml | awk -F= '{ print $2 }' | paste -sd, | sed -e 's/,/, /g'

cutawkの代わりに使用することもできますが、まだ言及していない他の基準があると思いますので、ここではawkを使用します。とにかく、これがcutバージョンです。

xml2 <sdfsdf.xml | cut -d= -f2 | paste -sd,
1
cas

xmlstartlet引数は少し注意が必要です。 xslの方法でそれらをテンプレート(-t)として表示する必要があります...

xmlstarlet sel -B -t -m '//text()' -c 'concat(.,",")' x1.xml

どこ:

  • -B:一般的にスペースを削除します
  • -t:xslの意味でのテンプレート
  • -m:xpathexpに一致
  • -c:xpathexpのコピー

この式は、余分な「、」を生成します。当然、通常のUnixツールを使用して次のことができます。

xmlstarlet sel -B -t -v '//text()' x1.xml | 
    sed -z 's/\n/, /g; s/$/\n/'
  • -t:テンプレート(xslの意味で)
  • -v:value-of(xpath式)
  • sed ...トリミングするには、
1
JJoao