xml形式のデータをcsv形式のデータに変換する。 基本的な変換規則は、一行の単位となる要素(XMLタグ)と、 項目に対応させる要素(もしくは属性)を、それぞれk=、f=によって指定する。 項目の値としては、 要素で囲われたテキスト、要素が出現するかどうか、 属性の値、属性が出現するかどうか、の4通りの方法を指定できる。
XMLのパーサーとしてはSAXを用いているので、XMLのサイズ制約はない。 XMLのエンコーディングがUTF-8以外であれば、UTF-8に変換されてCSVに出力される。 XMLデータは、整形式XML文書(well-formed XML document)であることを前提としている。 そうでない場合の処理結果は不定である。
典型例を、Table 3.49に示されたXMLデータを用いて示す。 より詳細な解説は、次節で行うとして、ここでは概略について解説する。 Table 3.50は、 行の単位を要素<b>とし(このような要素のことを「キー要素」と呼ぶ)、 項目として、要素bの属性attの値(CSV項目名b_att)、 要素cの属性pの値(b_p)とフラグ(b_p_f)、 そして要素dとa内のテキスト(dとa)を出力した結果である。 ここで、フラグとは、指定した要素もしくは属性が、出現するかどうかを0-1で出力したものである。 要素のテキスト出力は、指定した要素で囲われた範囲に出現する文字列を全て連結した文字列である。 ただし、スペースと制御文字は出力されないことに注意する。
Table 3.49: 入力XMLデータ <a att="aa"> <b att="bb1"> <c p="pp1" q="qq1"/> <d>text1</d> </b> <b att="bb2"> <c q="qq2"></c> <d>text2</d> </b> <b> <c p="pp3"/> <d>text3</d> </b> </a> Table 3.50: キー:/a/b、項目:b@att,c@p,d,/a
|
一行の単位となるキー要素(k=パラメータで指定)は絶対パスで指定する。 絶対パスは、ルート記号('/')から始めて、要素の階層を'/'記号で区切って表される。 本コマンドにおけるキー要素の役割は、キー要素の終了タグが出現した時に、以下の2点を実行することにある。
項目データを一行出力する。上記の例では、キー要素の終了タグ</b>が3回出現しており、 その度にCSVデータ一行が出力され改行される。
項目データを初期化する。ただし、キー要素の外側にある項目要素の出力データは初期化しない。 Table 3.50の要素aの出力において、テキストが連結されていくのは、 キー要素の終了タグが出現した時であっても、要素/aがキー要素/a/bより外側にあり、 出力データが初期化されないためである。
f=で要素をCSV項目として出力する場合、以下に示すフォーマットに従う。
要素パス[%フラグ]:CSV項目名
「項目名」は、出力されるCSVの項目名であり、必ず指定しなければならない。
要素を項目として出力する方法は2通りある。 一つは、指定の要素の開始タグと終了タグで囲われたテキストを出力する方法で、 他方は、指定した要素が存在するかどうかを0-1値で出力する方法である。 前者は、対象となる要素パスを指定し、 後者は、加えてフラグ%fを付与する。 また要素パスの指定方法は、絶対パスと相対パスの2通りある。 相対パスは、k=で指定された要素からのパスを指定する。 以下、Table 3.49のXMLについて、いくつかの要素パスの指定例を示す。
k=/a/bにおいて、f=:Bと指定すると、相対パスは空でキー要素と同じ要素となる。CSVの項目名はBである。
k=/a/bにおいて、f=c:Cとf=/a/b/c:Cは同じ意味である。 前者は相対パスによる指定、後者は絶対パスによる指定である。両者ともCSV項目名はCである。
f=d:Dは要素dで囲われたテキストを出力し、 f=d%f:Dは要素dが存在するかどうかを出力する。CSV項目名はDである。
k=/a/bにおいてf=/a:Aとした場合、 項目要素はキー要素の外側にあるため、a要素内に含まれるテキストが次々と結合される。 なぜならば、キー要素の終了タグが出現しても、項目要素の終了タグが出現しないために、その時点でデータがクリアされることがないためである。
f=で属性をCSV項目として出力する場合、以下に示すフォーマットに従う。
要素パス@要素名[%フラグ]:CSV項目名
「項目名」は、出力されるCSVの項目名であり、必ず指定しなければならない。
要素パスの指定は、要素の出力項目指定と同様である。 そして、属性名は、要素パスに続けて@で連結して指定する。 要素名の後に%fを付けることで、その要素が存在するかどうかを0-1値で出力する。
mxml2csv k= f= [i=] [o=] [-nfn] [-nfno] [-x] [-q] [tmpPath=] [--help] [--helpl] [--version]
k= |
一行の単位となる要素をルートからのパス名として指定する。 |
パスはルート記号’/’から始まり、要素を’/’でつなげることで指定する。 |
|
例: /article/sentence/chunk |
|
f= |
項目として出力する要素もしくは属性をカンマで区切って指定する。 |
フォーマットは以下のとおり。 |
|
要素パス[%フラグ]:CSV項目名 |
|
要素パス@要素名[%フラグ]:CSV項目名 |
|
i= |
xmlデータファイル名を指定する。省略時は標準入力から読み込まれる。 |
概要にて解説した例。 /a/bをキー要素として、5つのCSV項目を出力する。
$ more dat1.xml <a att="aa"> <b att="bb1"> <c p="pp1" q="qq1"/> <d>text1</d> </b> <b att="bb2"> <c q="qq2"></c> <d>text2</d> </b> <b> <c p="pp3"/> <d>text3</d> </b> </a> $ mxml2csv k=/a/b f=@att:b_att,c@p:c_p,c@p%f:c_p_f,d:d,/a:a i=dat1.xml o=rsl1.csv #END# kgxml2csv f=@att:b_att,c@p:c_p,c@p%f:c_p_f,d:d,/a:a i=dat1.xml k=/a/b o=rsl1.csv $ more rsl1.csv b_att,c_p,c_p_f,d,a bb1,pp1,1,text1,text1 bb2,,,text2,text1text2 ,pp3,1,text3,text1text2text3
基本例と同じ要素を絶対パスで指定する例。 /a/bをキー要素として、5つのCSV項目を出力する。
$ mxml2csv k=/a/b f=/a/b@att:b_att,/a/b/c@p:c_p,/a/b/c@p%f:c_p_f,/a/b/d:d,/a:a i=dat1.xml o=rsl2.csv #END# kgxml2csv f=/a/b@att:b_att,/a/b/c@p:c_p,/a/b/c@p%f:c_p_f,/a/b/d:d,/a:a i=dat1.xml k=/a/b o=rsl2.csv $ more rsl2.csv b_att,c_p,c_p_f,d,a bb1,pp1,1,text1,text1 bb2,,,text2,text1text2 ,pp3,1,text3,text1text2text3
絶対パスの例でキー要素をaに変更した例。 aの終了タグは一つしかないので、一行だけ出力されている。 f=で指定した/a/b@attは、2回出現しているが、最後に出現した値が出力されている。
$ mxml2csv k=/a f=/a/b@att:b_att,/a/b/c@p:c_p,/a/b/c@p%f:c_p_f,/a/b/d:d,/a:a i=dat1.xml o=rsl3.csv #END# kgxml2csv f=/a/b@att:b_att,/a/b/c@p:c_p,/a/b/c@p%f:c_p_f,/a/b/d:d,/a:a i=dat1.xml k=/a o=rsl3.csv $ more rsl3.csv b_att,c_p,c_p_f,d,a bb2,pp3,1,text3,text1text2text3