Flex Gateway新着情報
Governance新着情報
Monitoring API Manager<xml-module:xpath-extract>
操作は、XPath 式の評価をサポートしています。
XPath 式は各要素の任意の数値に一致する可能性があるため、この操作によって文字列のリストが返されます。要素が式に一致しない場合、この操作によって空のリストが返されます。
XPath 式も名前空間に対応しているため、この操作では名前空間のマッピングを使用できます。これらのマッピングは、参照される namespace-directory
で定義される namespaces
とマージされます。つまり、評価では両方の名前空間のマッピングのセットが組み合わされます。
MuleSoft は XPath 標準をサポートしていますが、DataWeave でも同じユースケースを実現でき、XML ドキュメントを抽出して変換するツールとして DataWeave をお勧めします。
次の例は、ウィリアム・シェイクスピアの戯曲『オセロ』の脚本を記載した XML を処理する方法を示しています。XML ファイルは次のようになります。
<?xml version="1.0"?>
<!--<!DOCTYPE PLAY SYSTEM "play.dtd">-->
<PLAY>
<TITLE>The Tragedy of Othello, the Moor of Venice</TITLE>
<FM>
<P>Text placed in the public domain by Moby Lexical Tools, 1992.</P>
<P>SGML markup by Jon Bosak, 1992-1994.</P>
<P>XML version by Jon Bosak, 1996-1998.</P>
<P>This work may be freely copied and distributed worldwide.</P>
</FM>
<PERSONAE>
<TITLE>Dramatis Personae</TITLE>
<PERSONA>DUKE OF VENICE</PERSONA>
<PERSONA>BRABANTIO, a senator.</PERSONA>
<PERSONA>Other Senators.</PERSONA>
<PERSONA>GRATIANO, brother to Brabantio.</PERSONA>
<PERSONA>LODOVICO, kinsman to Brabantio.</PERSONA>
<PERSONA>OTHELLO, a noble Moor in the service of the Venetian state.</PERSONA>
<PERSONA>CASSIO, his lieutenant.</PERSONA>
<PERSONA>IAGO, his ancient.</PERSONA>
<PERSONA>RODERIGO, a Venetian gentleman.</PERSONA>
<PERSONA>MONTANO, Othello's predecessor in the government of Cyprus.</PERSONA>
<PERSONA>Clown, servant to Othello. </PERSONA>
<PERSONA>DESDEMONA, daughter to Brabantio and wife to Othello.</PERSONA>
<PERSONA>EMILIA, wife to Iago.</PERSONA>
<PERSONA>BIANCA, mistress to Cassio.</PERSONA>
<PERSONA>Sailor, Messenger, Herald, Officers, Gentlemen, Musicians, and Attendants.</PERSONA>
</PERSONAE>
<SCNDESCR>SCENE Venice: a Sea-port in Cyprus.</SCNDESCR>
<PLAYSUBT>OTHELLO</PLAYSUBT>
<ACT><TITLE>ACT I</TITLE>
<SCENE><TITLE>SCENE I. Venice. A street.</TITLE>
<STAGEDIR>Enter RODERIGO and IAGO</STAGEDIR>
<SPEECH>
<SPEAKER>RODERIGO</SPEAKER>
<LINE>Tush! never tell me; I take it much unkindly</LINE>
<LINE>That thou, Iago, who hast had my purse</LINE>
<LINE>As if the strings were thine, shouldst know of this.</LINE>
</SPEECH>
.....
<!-- A LOT MORE CONTENT -->
xml
全文が上記の形式のテキストがあるとします。次のスクリプトを使用して、「handkerchief
」という単語が含まれるすべての行を抽出できます。
<xml-module:xpath-extract xpath="//LINE[contains(., $word)]"> (1)
<xml-module:context-properties>#[{'word': 'handkerchief'}]</xml-module:context-properties> (2)
</xml-module:xpath-extract>
xml
1 | $ プレフィックスを使用してコンテキストプロパティを参照する XPath 式を提供します。 |
2 | context-properties パラメーターで DataWeave を使用してコンテキストプロパティを生成します。 |
上記の XPath スクリプトにより、次の文字列のリストが出力されます。各 LINE
はリストの異なる項目です。
<LINE>For the same handkerchief?</LINE>
<LINE>What handkerchief?</LINE>
<LINE>What handkerchief?</LINE>
<LINE>Have you not sometimes seen a handkerchief</LINE>
<LINE>I know not that; but such a handkerchief--</LINE>
<LINE>Where should I lose that handkerchief, Emilia?</LINE>
<LINE>Lend me thy handkerchief.</LINE>
<LINE>That handkerchief</LINE>
<LINE>Fetch me the handkerchief: my mind misgives.</LINE>
<LINE>The handkerchief!</LINE>
<LINE>The handkerchief!</LINE>
<LINE>The handkerchief!</LINE>
<LINE>Sure, there's some wonder in this handkerchief:</LINE>
<LINE>But if I give my wife a handkerchief,--</LINE>
<LINE>But, for the handkerchief,--</LINE>
<LINE>Boding to all--he had my handkerchief.</LINE>
<LINE>--Handkerchief--confessions--handkerchief!--To</LINE>
<LINE>--Is't possible?--Confess--handkerchief!--O devil!--</LINE>
<LINE>mean by that same handkerchief you gave me even now?</LINE>
<LINE>By heaven, that should be my handkerchief!</LINE>
<LINE>And did you see the handkerchief?</LINE>
<LINE>That handkerchief which I so loved and gave thee</LINE>
<LINE>By heaven, I saw my handkerchief in's hand.</LINE>
<LINE>I saw the handkerchief.</LINE>
<LINE>It was a handkerchief, an antique token</LINE>
<LINE>O thou dull Moor! that handkerchief thou speak'st of</LINE>
<LINE>How came you, Cassio, by that handkerchief</LINE>
xml
デフォルトでは、この操作はメッセージペイロードレベルで XML ドキュメントを変換しようとします。ただし、content
パラメーターを使用して入力ドキュメントを提供できます。
<flow name="linesFromOthello">
<file:read path="othello.xml" target="othello" />
<xml-module:xpath-extract xpath="//LINE[contains(., $word)]">
<xml-module:content>#[vars.othello]</xml-module:content>
<xml-module:context-properties>#[{'word': 'handkerchief'}]</xml-module:context-properties>
</xml-module:xpath-extract>
</flow>
xml
上記の例では、他の場所 (この場合、ファイルシステムのファイル) からコンテンツを取得し、シンプルな式を使用して参照しています。
入力 XML ドキュメントに名前空間が異なる要素が含まれている場合があります。次に例を示します。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body foo="bar">
<ns1:echo xmlns:mule="http://simple.component.mule.org/">
<ns1:echo>Hello!</ns1:echo>
</ns1:echo>
</soap:Body>
</soap:Envelope>
xml
次の例では、XPath 式で使用される各 prefix
を対応する名前空間 uri
にマップします。
<flow name="xpathWithInlineNs">
<xml-module:xpath-extract xpath="/soap:Envelope/soap:Body/mule:echo/mule:echo">
<xml-module:namespaces>
<xml-module:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<xml-module:namespace prefix="mule" uri="http://simple.component.mule.org/"/>
</xml-module:namespaces>
</xml-module:xpath-extract>
</flow>
xml
しかし、同じ名前空間を使用する複数の XPath 式を実行する必要がある場合にはどうでしょうか? 毎回マッピングを実行せずに済むように、マッピングに namespace-directory
を作成し、そのディレクトリを参照することができます。次に例を示します。
<xml-module:namespace-directory name="fullNs"> (1)
<xml-module:namespaces>
<xml-module:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<xml-module:namespace prefix="mule" uri="http://simple.component.mule.org/"/>
</xml-module:namespaces>
</xml-module:namespace-directory>
<flow name="xpathWithFullNs">
<xml-module:xpath-extract
xpath="/soap:Envelope/soap:Body/mule:echo/mule:echo"
namespaceDirectory="fullNs"/> (2)(3)
</flow>
xml
1 | namespace-directory 要素を使用して、プレフィックスを実際の名前空間の URI にマップします。これらのプレフィックスは入力ドキュメントのプレフィックスに一致する必要があります。 |
2 | 続いて、これらのプレフィックスを XPath 式で参照できます。 |
3 | 最後に、namespaceDirectory パラメーターを使用してステップ 1 で作成されたマッピングを参照します。 |
最後に、ユースケースを組み合わせることができます。たとえば、マッピングが含まれるグローバルな namespaceDirectory
を用意して、操作レベルでマッピングを追加することができます。この組み合わせは、ドキュメントが多数あり、そのすべてに soap
名前空間が含まれているが 1 つのドキュメントにしか mule
名前空間が含まれていない場合に便利です。
<xml-module:namespace-directory name="partialNs"> (1)
<xml-module:namespaces>
<xml-module:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
</xml-module:namespaces>
</xml-module:namespace-directory>
<flow name="xpathWithMergedNs">
<xml-module:xpath-extract
xpath="/soap:Envelope/soap:Body/mule:echo/mule:echo"
namespaceDirectory="partialNs"> (2) (3)
<xml-module:namespaces>
<xml-module:namespace prefix="mule" uri="http://simple.component.mule.org/"/> (4)
</xml-module:namespaces>
</xml-module:xpath-extract>
</flow>
xml
1 | 以前と同じように namespace-directory を宣言しますが、共通の名前空間のみを指定します。 |
2 | XPath 式を提供します。 |
3 | 部分的な名前空間ディレクトリを参照します。 |
4 | 追加のマッピングを提供します。 |
マッピングと XPath 式で使用されるプレフィックスが入力ドキュメントで使用されるプレフィックスに一致することが重要です。
XML Module は、XPath を使用して値を抽出するための DataWeave 関数を提供します。これは、<choice>
ルーターや <foreach>
ルーターなどの場合に便利です。
この関数は任意の DataWeave 変換内でも使用できます。
次の例では、<foreach>
を使用して前のオセロの行の例のすべての行を反復処理し、それらを個別に処理します。
<foreach collection="#[XmlModule::xpath('//LINE', payload, {})]">
<flow-ref name="processLine" />
</foreach>
xml
最初の引数は XPath 式です。
2 つ目の引数は入力ドキュメントで、この場合、メッセージペイロードです。
3 つ目の引数はコンテキストプロパティです。この場合は必要ではないため、関数は空のオブジェクトを渡します ({}
)。
4 つ目の引数は省略可能であり、式の xpath を評価する名前空間を指定しています。
オセロの行の例に戻り、入力ドキュメントに単語 handkerchief
が含まれない場合に何かを実行するとします。
<choice>
<when expression="#[isEmpty(XmlModule::xpath('//LINE[contains(., \$word)]', vars.untrustedOthello, {'word': 'handkerchief'}))]">
<flow-ref name="alteredOthello" />
</when>
</choice>
xml
XmlModule::xpath
関数はリストを返すため、前の例では DataWeave isEmpty()
関数を使用して出力が空かどうかをテストします。
XPath 関数の最初に引数は、$word
コンテキストプロパティを使用する式です。
2 つ目の引数は変数内の入力ドキュメントです。
3 つ目の引数はコンテキストプロパティ値を提供します。
4 つ目の引数は省略可能であり、式の xpath を評価する名前空間を指定しています。
入力ドキュメントに XML 名前空間が含まれている場合、評価を実行するために XPath 関数にその情報が必要です。
次の例では、set-payload
コンポーネントを使用して書籍のタイトル、執筆者の名前、書籍の year タグを入力ドキュメントから取得します。このドキュメントには、明示的なデフォルトの xmlns
属性と、言語と執筆者に関するその他の xmlns
属性があります。
<?xml version="1.0" encoding="UTF-8"?>
<Book xmlns="http://www.books.org/2001/XMLSchema"
xmlns:lang="http://www.books.org/2001/XMLLang"
xmlns:author="http://www.books.org/2001/XMLAuthors">
<Title>Fundamentals</Title>
<Year>2001</Year>
<author:name>David Mills</author:name>
<lang:name>English</lang:name>
</Book>
xml
最初の例では、書籍のタイトルを取得するために set-payload
コンポーネントを次のように設定します。
<set-payload value="#[XmlModule::xpath('/b:Book/b:Title/text()', payload, {}, [{prefix:'b', uri:'http://www.books.org/2001/XMLSchema'}])]" />
xml
結果の出力は Fundamentals
です。
2 つ目の例では、執筆者の名前を取得するために set-payload
コンポーネントを次のように設定します。
<set-payload value="#[XmlModule::xpath('/b:Book/author:name/text()', payload, {}, [{prefix:'b', uri:'http://www.books.org/2001/XMLSchema'}, {prefix:'author', uri:'http://www.books.org/2001/XMLAuthors'}])]" />
xml
結果の出力は David Mills
です。
3 つ目の例では、書籍の year タグを取得するために set-payload
コンポーネントを次のように設定します。
<set-payload value="#[XmlModule::xpath('/b:Book/b:Year', payload, {}, [{prefix:'b', uri:'http://www.books.org/2001/XMLSchema'}])]" />
xml
xmlns
属性が含まれる結果の出力は <Year xmlns="http://www.books.org/2001/XMLSchema">2001</Year>
です。