目次

XML子要素同士の結合と出力例1

2024-04-15
1つのXML内の階層が違うノード要素を組み合わせる例

出力ファイルを分割する場合はXML子要素同士の結合と出力例2を参照。

希望の結果

XML内のfactoriesノードとitemsノードを結合して1行にしたい。ファイルは複数ある。

入力XML1
report-IN1.xml
<?xml version="1.0" encoding="UTF-8"?>
<info>
    <TITLE>これはサンプルです1</TITLE>
 
    <factories>
        <factoryA001><rank>A</rank><mainItem>P005</mainItem><capacity>2</capacity><note>精密加工</note></factoryA001>
        <factoryB001><rank>C</rank><mainItem>S001</mainItem><capacity>2</capacity></factoryB001>
        <factoryB010><rank>C</rank><mainItem>S020</mainItem><capacity>5</capacity><note>生産力に余力あり</note></factoryB010>
        <factoryC002><rank>A+</rank><note>ベテラン多数</note><mainItem>P005</mainItem><capacity>1</capacity></factoryC002>
        <depoD100><note>立地</note><capacity>3</capacity></depoD100>
        <depoD101><note>倉庫に問題</note><capacity>1</capacity></depoD101>
        <depoE201><note>ピックに問題</note><capacity>2</capacity></depoE201>
    </factories>
 
    <items>
        <item name="P001" desc="P型" type="C" />
        <item name="P005" desc="P型" type="C" />
        <item name="S001" desc="S型" type="X" />
        <item name="S020" desc="S型赤" type="X" />
        <item name="F001R" desc="F型復刻" type="J" />
    </items>
 
</info>
入力XML2
report-IN2.xml
<?xml version="1.0" encoding="UTF-8"?>
<info>
    <TITLE>これはサンプルです2</TITLE>
 
    <factories>
        <factoryF001><rank>C</rank><mainItem>P002</mainItem><capacity>2</capacity></factoryF001>
        <factoryG001><rank>C</rank><mainItem>S020</mainItem><capacity>3</capacity></factoryG001>
        <factoryG010><rank>D</rank><mainItem>S030</mainItem><capacity>2</capacity><note>設備老朽化</note></factoryG010>
        <depoA100><note>立地</note><capacity>3</capacity></depoA100>
        <depoC101><note>倉庫に問題</note><capacity>1</capacity></depoC101>
        <depoJ201><note>ピックに問題</note><capacity>2</capacity></depoJ201>
    </factories>
 
    <items>
        <item name="P002" desc="P型" type="C" />
        <item name="S030" desc="S型青" type="X" />
        <item name="S020" desc="S型赤" type="X" />
        <item name="J001" desc="J型" type="J" />
    </items>
 
</info>
出力CSV
report-OUT.csv
factory,rank,mainItem,capacity,note,desc
factoryF001,C,P002,2,,P型
factoryA001,A,P005,2,精密加工,P型
factoryC002,A+,P005,1,ベテラン多数,P型
factoryB001,C,S001,2,,S型
factoryB010,C,S020,5,生産力に余力あり,S型赤
factoryG001,C,S020,3,,S型赤
factoryG010,D,S030,2,設備老朽化,S型青

定義

フロー

Get data from XML1

factoriesノードの読み出し部分。正規表現で所定の形式の名称を指定し、複数ファイルを読み込み対象にする。

ループ XPath では、関数starts-with(),name()で処理対象ノードを指し示している。

 /info/factories/*[starts-with(name(),'factory')]

starts-with()は前方一致の検証関数。name()はノードの名前を返す関数。
ここの例では、名前が“factory”から始まるノードを処理対象とする指定になる。

そしてその選択されたノードから以下の情報を抜き出す。

Get data from XML2

itemsノードの読み出し部分。正規表現で所定の形式の名称を指定し、複数ファイルを読み込み対象にする。

ループXPathで“/info/items/item”を指定する。itemノードが処理対象になる。

そしてその選択されたノードから以下の情報を抜き出す。

行整列 1,行整列 2

それぞれ mainItem, name でXMLからの抽出結果をソートする。ソートしないと次のストリーム参照が正しく機能しない。

ストリーム参照

行整列 1の抽出項目 mainItem をキーに行整列 2を検索する。比較する項目nameをキー項目とする。
キーに一致するものがあれば項目name, descを、一致しなければnullを付与する。

テキストファイル出力

出力先をreport-OUT.csv とする。

カンマ区切りでMS932(windows-31j)の文字コードで出力する。

項目を絞っている。