Talend (Open Studio利用) でよく利用する tXMLMap について、慣れるまでに苦労した点を、つらつらと記録します。
1. Create empty element
Create empty element を false にしても、XMLで確認すると空ノードが生成されてしまっている事が多かった。
不具合かと思っていたが、実は分かっていなかっただけだったのでメモ。
値や属性が空文字の場合は、ノードが生成される。
値や属性が null の場合は、生成されない。
そういう事だった。
上のように設定した場合に、出力される XML は以下のようになる。
(null を直接代入するとコンパイルエラーになるので、上記設定では true ? null : "" としている。)
<root>
	<EmptyStringNode>
		<item></item> <!-- 値が空文字 -->
	</EmptyStringNode>
	<NullWithEmptyAttr dummy=""/> <!-- 属性が空文字 -->
</root>
Create empty element が true ならこうなる。比較すると一目瞭然:
<root>
	<EmptyStringNode>
		<item></item> <!-- 値が空文字 -->
	</EmptyStringNode>
	<NullNode>
		<item/> <!-- 値がnull -->
	</NullNode>
	<NullWithEmptyAttr dummy=""> <!-- 属性が空文字 -->
		<item/>
	</NullWithEmptyAttr>
	<NullWithNullAttr dummy=""> <!-- 属性がnull -->
		<item/>
	</NullWithNullAttr>
</root>
2. 複数loopとAll in one
XML から直接 XML へ値を移したい時は、loop element の位置と All in one の設定に注目する。
例えば次のような XML をまるごとコピーしたいと仮定する(実際のケースはもっと複雑だろうが)。
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <loop1> <!-- 親1に対して子3 -->
        <item>
            <A>A1</A>
            <B>B1</B>
        </item>
        <item>
            <A>A2</A>
            <B>B2</B>
        </item>
        <item>
            <A>A3</A>
            <B>B3</B>
        </item>
    </loop1>
    <loop2> <!-- 親1に対して子2 -->
        <item>
            <C>C1</C>
            <D>D1</D>
        </item>
        <item>
            <C>C2</C>
            <D>D2</D>
        </item>
    </loop2>
</root>
次のように設定してやれば、まるごとコピーできる。
必要となるループ回数は、3 + 2 で 5回。その結果を All in one でまとめる具合に。
試しに All in one を false にすると、5 rows 生成されることが確認できるはず。
3. ツリースキーマエディター
自分でもまったく愚かだったと思うのは、「ツリースキーマエディター」の存在にしばらく気づかなかった事。
それまで、XML の各ノードの型指定はできないものと思っていた。すべて文字列扱い?などと誤解していた。
例えば日付として認識できる値は、上図のように直接日付型として読み取れる。
わざわざ TalendDate.parseDate() を経由して加工する必要はない。(してました。)
4. おまけ:Document型とObject型の相互変換
例えば子ジョブに XML データを渡したいな、と考えても、context 経由では Document 型を渡せない。
でも、一度 Object 型に変換してやれば渡せる。
- contexts に Object 型の項目を用意する。(この例では xmlDoc)
- 子ジョブにも同じものを用意する。
- 親ジョブ側では、tRunJob の手前に tJavaRow を加える。
- tJavaRow で context.xmlDoc = input_row.payload;と代入する。(payload は Document型)
- tRunJob で xmlDoc を子ジョブへ渡す。
- 子ジョブの tJavaRow で output_row.payload = (Document)context.xmlDoc;でキャストして戻す。
(以上)





