DfromXml - XmlからDレコードの抽出

[ 英語 | 日本語 ]

形式

DfromXml [ -p Xpath ] [ options ] [ input-file.. ]

説明

DfromXmlは、 xmlファイルを読んでDレコードを作成する。 出力レコードは、-p xpathオプションで選択された各ノードから作成される。 -pオプションが省略されるた場合のXpathは"//*"となる。 これは、ルートノードを含むすべての階層のすべてのノードを選択する。

各入力ファイルは、正しいXMLファイルでなければならない。 DfromXmlは、各入力ファイルを読み込んで構文解析する。 構文解析でエラーがあると、その入力ファイルから出力レコードは作成されない。 構文解析の後、Xpath式が評価され、各選択ノードからDレコードが作成される。

入力ファイルのエンコーディングは、どんなものでもよい。 出力Dファイルは、カレントロケールの文字コードとなる。 ただし、UTF入出力機能が使われている場合は指定のUTFエンコーディングとなる。 出力文字コードに存在しない文字は、QUESTION MARK(?)に変換される。

Xpath

XpathはXMLツリーのノードを指定するための言語である。 デフォルトのXpathは"//*"で、ルートノードの下の任意のレベルの任意の要素ノードを意味する。 このデフォルトの出力は、通常目的のものより多すぎる このため、-p xpathオプションによって、求めるノードを選択する。 説明のため、次の例を使用する。

<?xml version="1.0" encoding="UTF-8"?>
<doc>/doc
  <a>text-a/doc/a
    <a>text-aa/doc/a/a
      <b>text-aab</b>/doc/a/a/b
    </a>
    <b>text-ab</b>/doc/a/b
  </a>
  <b>text-b1/doc/b[1]
    <a>text-b1a</a>/doc/b[1]/a
    <b>text-b1b</b>/doc/b[1]/b
  </b>
  <b>text-b2/doc/b[2]
    <a>text-b2a</a>/doc/b[2]/a
    <b>text-b2b</b>/doc/b[2]/b
  </b>
</doc>

この例で右の列に示しているのが、その行で始まる要素に対応するXpath式である。

[]でくくられた添え字は、同一レベルの同一名ノードを識別するためにつけられている。 添え字なしであれば、そのレベルの同一名ノードがすべて選択される。 たとえば、Xpath "/doc/b"は、 /doc/b[1]/doc/b[2]との両方を選択する。

ワイルドカード"*"は任意の要素ノードに対応する。 たとえば、"/doc/*"は、/doc/a/doc/b[1]および /doc/b[2]を選択する。

"//"は、任意個の"/*"またはルート("/")に対応する。 たとえば、"//b"は、/doc/a/a/b/doc/a/b/doc/b[1]/doc/b[1]/b/doc/b[2]および/doc/b[2]/bを選択する。 デフォルトXpath "//*"は、上記例のすべてのノードを選択する。

Xpath言語には他にも多くの演算子や機能があり、それらも使用できる。 ただ、多くの場合、"[]"、"*"および"//" の使用で用が足りるであろう。

名前空間

入力XMLファイルが名前空間を使用している場合、 Xpathのなかでもプレフィックスを使用しなければならない。 プレフィックスをURIと関連づけるには二つの方法が用意されている。 一つは暗黙宣言で、入力ファイルでのプレフィックス宣言を利用する。 もう一つは明示宣言で、-Nにより関連を宣言する。 入力ファイルが名前空間を使用していて-N optionが指定されていなければ、暗黙宣言が仮定される。

暗黙宣言では、入力ファイル中のタグに現れる形でXpath式を書くことができる。 次の例の右の列にあるような形で、Xpathを書けばよい。

<?xml version="1.0"?>
<oai_dc:dc/oai_dc:dc
    xmlns:oai_dc="http://www.openarchives..."
    xmlns:dc="http://purl.org/dc/elements...">
  <dc:title>DfromXml : D-2.3</dc:title>/oai_dc:dc/dc:title
  <dc:creator>Akira Miyazawa</dc:creator>/oai_dc:dc/dc:creator
</oai_dc:dc>

しかし、入力ファイルがデフォルト名前空間を使用しているとき、 物事はやや複雑になる。

<?xml version="1.0" encoding="UTF-8"?>
<OAI-PMH xmlns="http://www.openarchives.org/...">/D:OAI-PMH
  <ListRecords>/D:OAI-PMH/D:List
    <record>/D:OAI-PMH/D:List/D:record
    ........
    </record>
  </ListRecords>
</OAI-PMH>

デフォルト名前空間が使われているタグでは、上例の右の列にあるように、プレフィックス "D:"をつけなければならない。 この例では」、"-p //D:record"というような指定になる。

Xpath言語には、デフォルト名前空間というものはない。 プレフィックスのないXpath式は、入力ファイル中名前空間のスコープからはずれたタグだけを 指定していることになる。 入力ファイルが2つの異なるデフォルト名前空間を使用している場合、 DfromXmlは、2番目のデフォルト名前空間をプレフィックス D_ ということにする。次の例の右の列の3番目のXpathを見よ。

<?xml version="1.0"?>
<out>/out
  <in-1 xmlns="http://foo.org" >/out/D:in-1
    <in-2 xmlns="http://bar.org">/out/D:in-1/D_:in-2
    </in-2>
  </in-1>
</out>

DfromXml暗黙宣言は、 プレフィックスの衝突を避ける一般則を決めている。 各入力ファイルごとに、プログラムは入力ドキュメントの名前空間-プレフィックス関係づけ宣言を調べる。 もし、同じプレフィックスに異なる名前空間が関係づけられていた場合、2番目のプレフィックスに LOW LINE (_)を付加して、Xpathでのプレフィックスとする。 3番目のものには2つの(__)を加え、以下同様に処理される。 同じように"D_"は2番目のデフォルト名前空間と関連づけられ、 "D__"は3番目と関連づけられる。

明示宣言は、暗黙宣言より単純である。 -Nオプションによって、Xpathで使用するすべてのプレフィックスを宣言する。 -Nオプションのフォーマットは"プレフィックス=URI" で、-Nはいくつあってもよい。 このプレフィックスは-pオプションの中だけで有効で、 入力ファイルでのものと異なっていてもよい。 名前は、プレフィックス-ローカル部分のペアで比較されるのではなく、 (プレフィックスに関連づけられた)URI-ローカル部分のペアで比較される。

Dレコード出力

レコードノード

説明の便宜として、 レコードノード-p xpathで選択された ノードと定義する。

フィールドノード

レコードノードの直下のノードは、 Dフィールドに変換される。これらのノードをフィールドノードと呼ぶ。 出力Dレコードのフィールド順は、フィールドノードの 入力XMLファイルでの順にしたがう。 フィールドノードの要素名がDフィールド名となり、 フィールドノードのもとのテキストを集めたものtがDフィールド値となる。 レコードノードの直下にテキストがあれば、 "text"というフィールド名がつけられ、テキストそのものがフィールド値となる。

上例の/doc/aレコードノードとすると、

<a>text-a
  <a>text-aa
    <b>text-aab</b>
  </a>
  <b>text-ab</b>
</a>

DfromXmlは次のDレコードを出力する。

node:/doc/a
text:text-a
a:text-aa text-aab
text:
b:text-ab
text:

"node"フィールドは既定フィールド名フィールドでレコードノードを識別する。 この値は、名前空間が使われていない限り、 このノードを選択するXpath式として使用できる。 既定フィールド名の節参照。

"a"フィールドは/doc/a/aノードのテキストと、 /doc/a/a/bノードのテキストからなる。 2番目と3番目のtext"は空白文字だけからなる。 これらのフィールドは、終了タグ(たとえば</a>)と 開始タグ(たとえば<b>)との間の改行および行頭空白からなる。 これらのフィールドは無駄に見えるかもしれないが、DfromXmlはXML プロセッサの規約に従って、ドキュメント中のすべての文字をアプリケーションに渡す。 何が不要かを決めるのはアプリケーションで行うこと。 (ただし、/doc/aノードが混合内容でなく、文字データを持てないならば、 この例の場合"text-a"がなければ、空白文字だけのtext フィールドは作成されない)。

Dフィールドへの変換ではpredefined entities (&lt;, &gt;, &amp;, &quot;, &apos;) およびcharacter references (&#x4e00等)を通常の文字に変換することも行われる。

名前空間プレフィックスは、Dフィールド名には反映されない。 Dフィールド名になるのは、ローカル部分だけである。

ローモード出力

-rオプションをつけると、出力Dレコードはローモードで出力される。 ローモードでは、Dフィールドの値は、基本的にオリジナルのXMLでのフィールドノード からstart and end tagを取り除いたものとなる。 上の例で使った同じレコードノードから、

<a>text-a
  <a>text-aa
    <b>text-aab</b>
  </a>
  <b>text-ab</b>
</a>

DfromXml -rは次のDレコードを出力する。

node:/doc/a
text:text-a
a:text-aa <b>text-aab</b>
text:
b:text-ab
text:

コメントやそのほかの特殊ノードについては特殊ノードの節参照。 entity referencesを含むほとんどのXML constructは、そのまま出力される。 ただし、character referenceは通常の文字に直される。

属性

デフォルトでは、属性は出力に反映されない。 オプション-aにより、属性を出力に反映させることができる。 これには2つの方法がある。 1つは-a fオプションによる属性フィールド出力で、 もう1つが-a nオプションによる フィールド名バリエーションである。

オプション-a fによる属性フィールド出力では、 属性を要素のように取り扱い、 属性フィールドとよぶDフィールドを作成する。 属性フィールドのフィールド名は属性名の前に COMMERCIAL AT(@)文字をつけたものとなる。 フィールド値は、属性値を囲んでいる QUOTATION MARK(")を取り除いたものである。 レコードノードまたは フィールドノードの属性だけが 属性フィールドに変換され、 その他の属性は、変換されないで捨てられる。 レコードノード属性フィールドは、 ほかのフィールドノードのフィールドより前、 nodeフィールドの直後に置かれる。 フィールドノード属性フィールドは、 そのノードのフィールドの直後に置かれる。 次の例を見よ。

<doc lang="en">
  <rec a="va" b="vb">record node
    <f1 c="vc">field node
      <f11 d="vd">value11</f11>
      <f12 d="vd">value12</f12>
    </f1>
    <f2 e="ve">valuef2</f2>field node
  </rec>
</doc>

オプション"-a f"をつけると、次のようなDレコードとなる。

node:/doc/rec
@a:va
@b:vb
f1:value11value12
@c:vc
f2:valuef2
@e:ve

外側のノード(<doc>)や、内側のノード (<f11>, <f12>)の属性は反映されていないことに注意。

オプション-a nによるフィールド名バリエーション では、属性は、Dフィールド名の一部となる。 これは、フィールドノードの属性だけに適用され、 レコードノードの属性は無視される。

オプション-a fの典型的な使用法は次のようなものである。

<title lang="en">Algorithms</title>
<title lang="fr">Algorithmique</title>

これらの要素が-a nオプションつきでフィールドノード となると、次のようなDフィールドに変換される。

title-en:Algorithms
title-fr:Algorithmique

さらに"-a nフィールド名仕様"という形式で フィールド名仕様を指定することもできる。 フィールド名仕様は文字列で、要素名の後ろに付加されてDフィールド名を作る。 このとき、フィールド名仕様中の "\a" は属性名で置き換えられ、 "\v"は属性値で置き換えられ、 "\\"は"\"で置き換えられる。 属性が複数あれば、各属性ごとにこれを行う。 フィールド名仕様がなかった場合デフォルトは"-\v"である。 上記例にあるように、"-en" および"-fr" が要素名 "title"に付加されてDフィールド名となっている。

次の例はフィールド名仕様の説明のための例である。 フィールドノードが次のようなとき、

<field a="va" b="vb">value</field>

オプション"-a n-\a=\v"とするとDfromXmlは、

field-a=va-b=vb:value

を出力する。

特殊ノード

XMLには要素や属性以外にいくつかの特殊ノードが存在する。 コメント、processing instructions、CDATA sections、entity referencesである。 次のテーブルは、それらが出力Dレコードにどのように反映されるかを示す。

特殊ノード
ノード フィールドノード中 フィールドノード中(ローモード フィールドノード フィールドノードローモード
comment
<!--text-->
出力なし <!--text--> comment:text comment:<!--text-->
processing instruction
<?target instruction?>
出力なし <?target instruction?> PI:target instruction PI:<?target instruction?>
CDATA section
<![CDATA[text]]>
text <![CDATA[text]]> CDATA:text CDATA:<![CDATA[text]]>
entity reference
&name;
replacement text &name; ENTITY:name ENTITY:&name;

これらのノードがレコードノードとして選択されることは普通ない。 ただし、レコードノードとなったときは、フィールドノードの場合と同様に扱われる。

オプション

-p xpath
レコードノードを選択するXpath式。 デフォルトは"//*"で、すべての要素ノード。
-N プレフィックス=URI
明示宣言の場合のプレフィックスとURIの関連づけ。 複数個あってよい。
-e encoding
入力ファイルのエンコーディング。 通常、このオプションを必要とすることはない。 しかし、入力ファイルに正しいエンコーディング情報がなく UTF-8でない場合、 このオプションが必要となる。 エンコーディング名は、iconv(1)コマンドの受け入れる 名前で指定する。 たいていのUNIXの場合、iconv -lコマンドでエンコーディング名の リストが得られる。 WINDOWSの場合、エンコーディング名リスト参照のこと。
-a v
属性を属性フィールドオプションで出力。
-a nフィールド名仕様
属性をフィールド名バリエーションオプションでフィールド名に変換。
-r
ローモード出力; 出力フィールドには、下位レベルのタグが含まれる。 entity references(&lt;等)は、そのままの形で出力される。
-n newline-replacement
改行制御文字を代替する文字列を指定する。 このオプションの指定がない場合、NULL文字列となる。 (改行制御文字は単に除去される)。
-F
レコードの入力ファイル名を
"filename"フィールドに出力。
-D odatautf=8|16|32
UTF出力(UTF入出力機能参照)。
idatautfは無視される。

既定フィールド名

filename:
-Fオプションが指定されたとき、 各レコードの先頭のフィールドとして。 値はそのレコードの入力ファイル名で、シェルにより展開された形をしている。 ただし、入力が標準入力の場合、このフィールドは付加されない。
node:
他のフィールドの前で、もしあれば、filenameフィールドの後ろ。 レコードノードを示すXpath式。 このフィールドの値は、名前空間が使われていない限り、-p xpathオプションで、 このノードを示す式として使用できる。 入力ドキュメント中に名前空間が使われている場合、pathの各stepには 入力ドキュメント中で使われているprefixed(もしあれば)がつけられる。 一般的には、そのままの形で-pオプションに使用することはできない。 しかし次の条件をすべて満たしていれば、-pオプションで使用できる。
  1. 暗黙宣言を使用すること。
  2. デフォルト名前空間が使われていないこと
  3. 同じプレフィックスが異なる名前空間と結びつけられていないこと。
text:
レコードノードの直下にテキストがある場合。
comment:
レコードノードの直下にコメントがある場合。
PI:
レコードノードの直下にプロセシングインフォメーションがある場合。
CDATA:
レコードノードの直下にCDATAセクションがある場合。
ENTITY:
レコードノードの直下にnon-predefined entity reference がある場合。

使用例

もっとも単純な使用法では、デフォルトXpath "//*" で、すべての要素ノードからDレコードを作る。

DfromXml foo.xml

OAI-PMH (Open Archives Initiative Protocol for Metadata Harvesting) のレスポンス(OAI-PMHの例示フォーマット)から、ダブリンコアメタデータを取り出す。

DfromXml -p //oai_dc:dc response.xml

デフォルト名前空間を一つだけ使っているXMLファイルから<record>ノードを選択する。

DfromXml -p //D_:record bar.xml

ENVIRONMENT

Dodatautf
for UTF入出力機能参照。
Didatautfは無視される。

メッセージ

マニュアル D_msg参照。

このほか、XML構文解析と、Xpath処理系からのメッセージが 出力されうる。これらについては、libxml2のマニュアル参照。

参照

DintroDtoXmlDfromHtmlD_msg

AUTHOR

MIYAZAWA Akira


miyazawa@nii.ac.jp
2006