XML モジュールでの XQuery の使用

<xml-module:xquery-transform> 操作は、XQuery 式の評価をサポートしています。

XQuery 式は各要素の任意の数値に一致する可能性があるため、この操作によって文字列のリストが返されます。要素が式に一致しない場合、この操作によって空のリストが返されます。

MuleSoft は XQuery 標準をサポートしていますが、DataWeave でも同じユースケースを実現でき、XML ドキュメントを抽出して変換するツールとして DataWeave をお勧めします。

次の例は、XQuery を使用してブックリストを操作する方法を示しています。

入力: ブックリスト
<?xml version="1.0" encoding="UTF-8"?>
<BOOKLIST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="books.xsd">
    <BOOKS>
        <ITEM CAT="MMP">
            <TITLE>Pride and Prejudice</TITLE>
            <AUTHOR>Jane Austen</AUTHOR>
            <PUBLISHER>Modern Library</PUBLISHER>
            <PUB-DATE>2002-12-31</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>9</PRICE>
            <QUANTITY>187</QUANTITY>
            <ISBN>0679601686</ISBN>
            <PAGES>352</PAGES>
            <DIMENSIONS UNIT="in">8.3 5.7 1.1</DIMENSIONS>
            <WEIGHT UNIT="oz">6.1</WEIGHT>
        </ITEM>
        <ITEM CAT="P">
            <TITLE>Wuthering Heights</TITLE>
            <AUTHOR>Charlotte Bronte</AUTHOR>
            <PUBLISHER>Penguin Classics</PUBLISHER>
            <PUB-DATE>2002-12-31</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>9.040000000000001</PRICE>
            <QUANTITY>113</QUANTITY>
            <ISBN>0141439556</ISBN>
            <PAGES>430</PAGES>
            <DIMENSIONS UNIT="in">1.0 5.2 7.8</DIMENSIONS>
            <WEIGHT UNIT="oz">11.2</WEIGHT>
        </ITEM>
        <ITEM CAT="P">
            <TITLE>Tess of the d'Urbervilles</TITLE>
            <AUTHOR>Thomas Hardy</AUTHOR>
            <PUBLISHER>Bantam Classics</PUBLISHER>
            <PUB-DATE>1984-05-01</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>12.5</PRICE>
            <QUANTITY>85</QUANTITY>
            <ISBN>0553211684</ISBN>
            <PAGES>480</PAGES>
            <DIMENSIONS UNIT="in">6.8 4.2 0.8</DIMENSIONS>
            <WEIGHT UNIT="oz">7.7</WEIGHT>
        </ITEM>
        <ITEM CAT="P">
            <TITLE>Jude the Obscure</TITLE>
            <AUTHOR>Thomas Hardy</AUTHOR>
            <PUBLISHER>Penguin Classics</PUBLISHER>
            <PUB-DATE>1998-09-01</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>7</PRICE>
            <QUANTITY>129</QUANTITY>
            <ISBN>0140435387</ISBN>
            <PAGES>528</PAGES>
            <DIMENSIONS UNIT="in">7.8 5.2 0.9</DIMENSIONS>
            <WEIGHT UNIT="oz">10.9</WEIGHT>
        </ITEM>
        <ITEM CAT="H">
            <TITLE>The Big Over Easy</TITLE>
            <AUTHOR>Jasper Fforde</AUTHOR>
            <PUBLISHER>Hodder &amp; Stoughton</PUBLISHER>
            <PUB-DATE>2005-07-11</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>14.55</PRICE>
            <QUANTITY>129</QUANTITY>
            <ISBN>0340835672</ISBN>
            <PAGES>346</PAGES>
            <DIMENSIONS UNIT="cm">22.5 18.0 3.5</DIMENSIONS>
            <WEIGHT UNIT="g">390</WEIGHT>
        </ITEM>
        <ITEM CAT="P">
            <TITLE>The Eyre Affair</TITLE>
            <AUTHOR>Jasper Fforde</AUTHOR>
            <PUBLISHER>Penguin</PUBLISHER>
            <PUB-DATE>2003-02-25</PUB-DATE>
            <LANGUAGE>English</LANGUAGE>
            <PRICE>15</PRICE>
            <QUANTITY>129</QUANTITY>
            <ISBN>0142001805</ISBN>
            <PAGES>384</PAGES>
            <DIMENSIONS UNIT="in">7.8 5.0 0.9</DIMENSIONS>
            <WEIGHT UNIT="oz">9.0</WEIGHT>
        </ITEM>
    </BOOKS>
    <CATEGORIES DESC="Miscellaneous categories">
        <CATEGORY CODE="P" DESC="Paperback"/>
        <CATEGORY CODE="MMP" DESC="Mass-market Paperback"/>
        <CATEGORY CODE="H" DESC="Hard Cover"/>
    </CATEGORIES>
</BOOKLIST>

次の例では、XQuery を使用して上記のブックリストを変換しています。

XQuery 変換スクリプト
 <xml-module:xquery-transform>
    <xml-module:xquery><![CDATA[
        xquery version "3.0";
        declare copy-namespaces no-preserve, inherit;
        declare variable $document external;

        for $b in $document//BOOKS/ITEM
        order by string-length($b/TITLE) return
        <book>
            <author> { $b/AUTHOR } </author>
            <title> { $b/TITLE } </title>
        </book>
    ]]></xml-module:xquery>
</xml-module:xquery-transform>

次の XQuery 変換により、各エントリが次の各 <book> 要素に対応する文字列のリストが生成されます。

出力 XML
<book>
   <author>
      <AUTHOR>Jasper Fforde</AUTHOR>
   </author>
   <title>
      <TITLE>The Eyre Affair</TITLE>
   </title>
</book>
<book>
   <author>
      <AUTHOR>Thomas Hardy</AUTHOR>
   </author>
   <title>
      <TITLE>Jude the Obscure</TITLE>
   </title>
</book>
<book>
   <author>
      <AUTHOR>Charlotte Bronte</AUTHOR>
   </author>
   <title>
      <TITLE>Wuthering Heights</TITLE>
   </title>
</book>
<book>
   <author>
      <AUTHOR>Jasper Fforde</AUTHOR>
   </author>
   <title>
      <TITLE>The Big Over Easy</TITLE>
   </title>
</book>
<book>
   <author>
      <AUTHOR>Jane Austen</AUTHOR>
   </author>
   <title>
      <TITLE>Pride and Prejudice</TITLE>
   </title>
</book>
<book>
   <author>
      <AUTHOR>Thomas Hardy</AUTHOR>
   </author>
   <title>
      <TITLE>Tess of the d'Urbervilles</TITLE>
   </title>
</book>

デフォルトでは、この操作はメッセージペイロードレベルで XML ドキュメントを変換しようとします。ただし、content パラメータを使用して入力ドキュメントを提供できます。

例: コンテンツパラメータの使用
<flow name="books">
    <file:read path="books.xml" target="books" />
    <xml-module:xquery-transform>
        <xml-module:content>#[vars.books]</xml-module:content>
        <xml-module:xquery><![CDATA[
            xquery version "3.0";
            declare copy-namespaces no-preserve, inherit;
            declare variable $document external;

            for $b in $document//BOOKS/ITEM
            order by string-length($b/TITLE) return
            <book>
                <author> { $b/AUTHOR } </author>
                <title> { $b/TITLE } </title>
            </book>
        ]]></xml-module:xquery>
    </xml-module:xquery-transform>
</flow>

上記の例では、他の場所 (この場合、ファイルシステムのファイル) からコンテキストを取得し、シンプルな式から参照しています。

XQuery スクリプトの個別のファイルへの外部化

XQuery スクリプトを Mule アプリケーションに組み込まずに済むように、次のように、ファイルを使用してモジュールに渡すことができます。

<xml-module:xquery-transform>
    <xml-module:xquery>${file::scripts/books.xquery}</xml-module:xquery>
</xml-module:xquery-transform>

より複雑なユースケースでは、使用するスクリプトが外的な条件に応じて異なる場合もあります。たとえば、使用する実際の変換が userID に応じて異なるマルチテナントのインテグレーションを考えてみます。

複雑な例
<flow name="multitenantExample">
    <http:listener path="transform" allowedMethods="POST" config-ref="httpListener" /> (1)
    <file:read path="#['xquery/$(attributes.queryParam.userId).xquery']" target="xquery" /> (2)
     <xml-module:xquery-transform>
        <xml-module:xquery>#[vars.xquery]</xml-module:xquery>
    </xml-module:xquery-transform>
</flow>
  1. このフローは HTTP 要求によってトリガされます。

  2. この例では、userID がクエリパラメータとして提供されていることと想定し、ファイルコネクタを使用して正しい XQuery スクリプトを読み取り、変数に保存します。

  3. モジュールは、Read 操作を使用して取得された XQuery スクリプトを参照する式を使用して変換を実行します。

HTTP コネクタとファイルコネクタは単に例として使用しています。同様のユースケースを実行するために必要なわけではありません。

コンテキストプロパティおよび複数の入力の使用

対応する xpathxslt と同じように、xquery 操作は引数を変換に渡せるコンテキストパラメータをサポートしています。

たとえば、上記の books XML を次の cities XML ドキュメントと組み合わせるとします。

入力
<?xml version="1.0" encoding="UTF-8"?>
<cities>
    <city name="milan" country="italy" pop="5"/>
    <city name="paris" country="france" pop="7"/>
    <city name="munich" country="germany" pop="4"/>
    <city name="lyon" country="france" pop="2"/>
    <city name="venice" country="italy" pop="1"/>
</cities>

このユースケースの例を見てみましょう。

XQuery 変換スクリプト
<flow name="multipleInputs">
  <file:read path="books.xml" target="books" />
  <file:read path="cities.xml" target="cities" /> (1)
  <xml-module:xquery-transform>
    <xml-module:xquery>
      <![CDATA[
          xquery version "3.0";
          declare variable $document external;
          declare variable $cities external; (2)
          declare variable $books external; (3)
          <mixes>
            {
              for $b in fn:doc($books)/BOOKLIST/BOOKS/ITEM,
                $c in fn:doc($cities)/cities/city (4)

              return <mix title="{$b/TITLE/text()}" city="{$c/@name}" /> (5)
            }
          </mixes>
      ]]>
    </xml-module:xquery>
    <xml-module:context-properties>
      #[{'books' : vars.books, 'cities': vars.cities}]
    </xml-module:context-properties> (6)
  </xml-module:xquery-transform>
</flow>
1 入力ドキュメントを読み取り、コンテンツを変数に保存します。この例ではファイルコネクタを使用していますが、任意のデータソースを使用できます。
2 XQuery スクリプトで $cities 変数を宣言します。
3 XQuery スクリプトで $books 変数を宣言します。
4 $ プレフィックスを使用して両方のドキュメントを参照し、両方を反復します。
5 出力要素を生成します。
6 DataWeave および <xml-module:context-properties> パラメータを使用してプロパティをバインドします。

スクリプトは、1 つの項目のみが含まれる文字列のリストを出力します。

出力
<mixes>
   <mix title="Pride and Prejudice" city="milan"/>
   <mix title="Pride and Prejudice" city="paris"/>
   <mix title="Pride and Prejudice" city="munich"/>
   <mix title="Pride and Prejudice" city="lyon"/>
   <mix title="Pride and Prejudice" city="venice"/>
   <mix title="Wuthering Heights" city="milan"/>
   <mix title="Wuthering Heights" city="paris"/>
   <mix title="Wuthering Heights" city="munich"/>
   <mix title="Wuthering Heights" city="lyon"/>
   <mix title="Wuthering Heights" city="venice"/>
   <mix title="Tess of the d'Urbervilles" city="milan"/>
   <mix title="Tess of the d'Urbervilles" city="paris"/>
   <mix title="Tess of the d'Urbervilles" city="munich"/>
   <mix title="Tess of the d'Urbervilles" city="lyon"/>
   <mix title="Tess of the d'Urbervilles" city="venice"/>
   <mix title="Jude the Obscure" city="milan"/>
   <mix title="Jude the Obscure" city="paris"/>
   <mix title="Jude the Obscure" city="munich"/>
   <mix title="Jude the Obscure" city="lyon"/>
   <mix title="Jude the Obscure" city="venice"/>
   <mix title="The Big Over Easy" city="milan"/>
   <mix title="The Big Over Easy" city="paris"/>
   <mix title="The Big Over Easy" city="munich"/>
   <mix title="The Big Over Easy" city="lyon"/>
   <mix title="The Big Over Easy" city="venice"/>
   <mix title="The Eyre Affair" city="milan"/>
   <mix title="The Eyre Affair" city="paris"/>
   <mix title="The Eyre Affair" city="munich"/>
   <mix title="The Eyre Affair" city="lyon"/>
   <mix title="The Eyre Affair" city="venice"/>
</mixes>

関連情報

Was this article helpful?

💙 Thanks for your feedback!

Edit on GitHub