XML サポート - XML ペイロードの処理

Spring Integration の XML サポートは、Spring Integration のコアを次のコンポーネントで拡張します。

この依存関係をプロジェクトに含める必要があります。

Maven
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-xml</artifactId>
    <version>5.5.8</version>
</dependency>
Gradle
compile "org.springframework.integration:spring-integration-xml:5.5.8"

これらのコンポーネントにより、Spring Integration での XML メッセージの操作が簡単になります。メッセージングコンポーネントは、java.lang.Stringorg.w3c.dom.Documentjavax.xml.transform.Source のインスタンスを含むさまざまな形式で表される XML で機能します。ただし、DOM 表現が必要な場合(たとえば、XPath 式を評価するため)、String ペイロードは必要な型に変換されてから、String に変換されます。DocumentBuilder のインスタンスを必要とするコンポーネントは、インスタンスを提供しない場合、名前空間対応のインスタンスを作成します。ドキュメントの作成をより細かく制御する必要がある場合は、適切に構成された DocumentBuilder のインスタンスを提供できます。

名前空間サポート

Spring Integration XML モジュール内のすべてのコンポーネントは、名前空間のサポートを提供します。名前空間のサポートを有効にするには、Spring Integration XML モジュールのスキーマをインポートする必要があります。次の例は、典型的なセットアップを示しています。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"
  xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration
    https://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/xml
    https://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd">
</beans>

XPath 式

Spring Integration XML モジュール内のコンポーネントの多くは、XPath 式で機能します。これらの各コンポーネントは、トップレベル要素として定義されている XPath 式を参照するか、ネストされた <xpath-expression/> 要素を使用します。

XPath 式のすべての形式により、Spring org.springframework.xml.xpath.XPathExpressionFactory を使用する XPathExpression が作成されます。XPath 式が作成されると、クラスパスで使用できる最適な XPath 実装が使用されます(JAXP 1.3 + または Jaxen、JAXP が推奨されます)。

内部的には、Spring Integration は Spring Web Services プロジェクト(https://www.spring.io/spring-ws (英語) )によって提供される XPath 機能を使用します。具体的には、Spring Web Services XML モジュール(spring-xml-x.x.x.jar)を使用します。より深い理解については、https://docs.spring.io/spring-ws/docs/current/reference/#xpath のそれぞれのドキュメントを参照してください。

以下は、xpath-expression エレメントで使用可能なすべての構成パラメーターの概要です。次のリストは、xpath-expression エレメントで使用可能な属性を示しています。

<int-xml:xpath-expression expression="" (1)
          id=""                         (2)
          namespace-map=""              (3)
          ns-prefix=""                  (4)
          ns-uri="">                    (5)
    <map></map>                         (6)
</int-xml:xpath-expression>
1XPath 式を定義します。必須。
2 基礎となる Bean 定義の識別子。org.springframework.xml.xpath.XPathExpression のインスタンスです。オプション。
3 名前空間を含むマップへの参照。マップのキーはネームスペースプレフィックスを定義し、マップの値はネームスペース URI を設定します。この属性と map 要素、または ns-prefix と ns-uri 属性の両方を指定することは無効です。オプション。
4 名前空間プレフィックスを XPath 式要素の属性として直接設定できます。ns-prefix を設定する場合、ns-uri 属性も設定する必要があります。オプション。
5 名前空間 URI を XPath 式要素の属性として直接設定できます。ns-uri を設定する場合、ns-prefix 属性も設定する必要があります。オプション。
6 名前空間を含むマップを定義します。map 子要素は 1 つのみ許可されます。マップのキーはネームスペースプレフィックスを定義し、マップの値はネームスペース URI を設定します。この要素と map 属性の両方を指定したり、ns-prefix および ns-uri 属性を設定したりすることは無効です。オプション。
XPath 式への名前空間(オプション)の提供

XPath Expression Element の場合、名前空間情報を構成パラメーターとして提供できます。次の選択肢のいずれかを使用して、名前空間を定義できます。

  • namespace-map 属性を使用してマップを参照する

  • map サブ要素を使用して名前空間のマップを提供します

  • ns-prefix および ns-uri 属性を指定します

3 つのオプションはすべて相互に排他的です。設定できるオプションは 1 つだけです。

次の例は、前述の XML 名前空間を設定するオプションなど、XPath 式を使用するいくつかの異なる方法を示しています。

<int-xml:xpath-filter id="filterReferencingXPathExpression"
                      xpath-expression-ref="refToXpathExpression"/>

<int-xml:xpath-expression id="refToXpathExpression" expression="/name"/>

<int-xml:xpath-filter id="filterWithoutNamespace">
    <int-xml:xpath-expression expression="/name"/>
</int-xml:xpath-filter>

<int-xml:xpath-filter id="filterWithOneNamespace">
    <int-xml:xpath-expression expression="/ns1:name"
                              ns-prefix="ns1" ns-uri="www.example.org"/>
</int-xml:xpath-filter>

<int-xml:xpath-filter id="filterWithTwoNamespaces">
    <int-xml:xpath-expression expression="/ns1:name/ns2:type">
        <map>
            <entry key="ns1" value="www.example.org/one"/>
            <entry key="ns2" value="www.example.org/two"/>
        </map>
    </int-xml:xpath-expression>
</int-xml:xpath-filter>

<int-xml:xpath-filter id="filterWithNamespaceMapReference">
    <int-xml:xpath-expression expression="/ns1:name/ns2:type"
                              namespace-map="defaultNamespaces"/>
</int-xml:xpath-filter>

<util:map id="defaultNamespaces">
    <util:entry key="ns1" value="www.example.org/one"/>
    <util:entry key="ns2" value="www.example.org/two"/>
</util:map>
デフォルトのネームスペースでの XPath 式の使用

デフォルトのネームスペースを使用する場合、予想とは異なる動作をする可能性があります。次の XML ドキュメント(2 冊のオーダーを表す)があるとします。

<?xml version="1.0" encoding="UTF-8"?>
<order>
    <orderItem>
        <isbn>0321200683</isbn>
        <quantity>2</quantity>
    </orderItem>
    <orderItem>
        <isbn>1590596439</isbn>
        <quantity>1</quantity>
    </orderItem>
</order>

このドキュメントは名前空間を宣言していません。次の XPath 式の適用は期待どおりに機能します。

<int-xml:xpath-expression expression="/order/orderItem" />

同じ式が次の XML ファイルでも機能すると予想される場合があります。

<?xml version="1.0" encoding="UTF-8"?>
<order xmlns="http://www.example.org/orders">
	<orderItem>
		<isbn>0321200683</isbn>
		<quantity>2</quantity>
	</orderItem>
	<orderItem>
		<isbn>1590596439</isbn>
		<quantity>1</quantity>
	</orderItem>
</order>

前の例は前の例とまったく同じに見えますが、デフォルトの名前空間を宣言しています。

ただし、この場合、以前の XPath 式(/order/orderItem)は失敗します。

この課題を解決するには、ns-prefix 属性と ns-uri 属性を設定するか、namespace-map 属性を設定して、名前空間プレフィックスと名前空間 URI を指定する必要があります。名前空間 URI は、XML ドキュメントで宣言された名前空間と一致する必要があります。前の例では、http://www.example.org/orders (英語) です。

ただし、ネームスペースプレフィックスは任意に選択できます。実際、空の文字列を指定すると実際に機能します。(ただし、null は許可されません)空の文字列で構成される名前空間プレフィックスの場合、Xpath 式はコロン(":")を使用してデフォルトの名前空間を示す必要があります。コロンを省略すると、XPath 式は一致しません。次の XPath 式は、前の例の XML ドキュメントと一致します。

<int-xml:xpath-expression expression="/:order/:orderItem"
    ns-prefix="" ns-uri="https://www.example.org/prodcuts"/>

また、他の任意に選択されたネームスペースプレフィックスを提供することもできます。次の XPath 式(myorder 名前空間プレフィックスを使用)も一致します。

<int-xml:xpath-expression expression="/myorder:order/myorder:orderItem"
    ns-prefix="myorder" ns-uri="https://www.example.org/prodcuts"/>

名前空間 URI は、プレフィックスではなく、本当に重要な情報です。https://github.com/jaxen-xpath/jaxen[Jaxen] はポイントを非常にうまく要約しています:

XPath 1.0 では、接頭辞のない名前はすべて修飾されていません。XPath 式で使用されるプレフィックスが、クエリ対象のドキュメントで使用されるプレフィックスと同じである必要はありません。プレフィックスではなく、名前空間 URI のみが一致する必要があります。

XML ペイロードの変換

このセクションでは、XML ペイロードを変換する方法について説明します

Transformers を Bean として構成する

このセクションでは、以下のトランスフォーマーの動作と、Bean として構成する方法について説明します。

XML トランスフォーマーはすべて、AbstractTransformer (Javadoc) または AbstractPayloadTransformer (Javadoc) のいずれかを継承するため、Transformer (Javadoc) を実装します。XML トランスフォーマーを Spring Integration で Bean として構成する場合、通常、MessageTransformingHandler (Javadoc) と組み合わせて Transformer を構成します。これにより、トランスフォーマーをエンドポイントとして使用できます。最後に、名前空間のサポートについて説明します。これにより、トランスフォーマーを XML の要素として構成できます。

UnmarshallingTransformer

UnmarshallingTransformer (Javadoc) を使用すると、Spring OXM Unmarshaller の実装を使用して、XML Source のマーシャリングを解除できます。Spring のオブジェクト / XML マッピングのサポートは、JAXB [Wikipedia] (英語) キャスター (英語) JiBX [Wikipedia] (英語) などを使用してマーシャリングとアンマーシャリングをサポートするいくつかの実装を提供します。アンマーシャラーには Source のインスタンスが必要です。メッセージペイロードが Source のインスタンスでない場合でも、変換は試行されます。現在、StringFilebyte[]org.w3c.dom.Document ペイロードがサポートされています。Source へのカスタム変換を作成するには、SourceFactory (Javadoc) の実装を挿入できます。

SourceFactory を明示的に設定しない場合、UnmarshallingTransformer のプロパティはデフォルトで DomSourceFactory (Javadoc) に設定されます。

バージョン 5.0 以降、UnmarshallingTransformer は受信ペイロードとして org.springframework.ws.mime.MimeMessage もサポートしています。これは、SOAP を介して MTOM 添付ファイル付きの生の WebServiceMessage を受信する場合に役立ちます。詳細については、MTOM サポートを参照してください。

次の例は、非整列化トランスフォーマーを定義する方法を示しています。

<bean id="unmarshallingTransformer" class="o.s.i.xml.transformer.UnmarshallingTransformer">
    <constructor-arg>
        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="org.example" />
        </bean>
    </constructor-arg>
</bean>
MarshallingTransformer を使用する

MarshallingTransformer (Javadoc) では、Spring OXM Marshaller を使用してオブジェクトグラフを XML に変換できます。デフォルトでは、MarshallingTransformer は DomResult を返します。ただし、StringResultFactory などの代替 ResultFactory を構成することにより、結果の型を制御できます。多くの場合、ペイロードを別の XML 形式に変換する方が便利です。そのためには、ResultTransformer を構成します。Spring 統合は、String に変換するものと Document に変換するものの 2 つの実装を提供します。次の例では、ドキュメントに変換するマーシャリングトランスフォーマーを構成します。

<bean id="marshallingTransformer" class="o.s.i.xml.transformer.MarshallingTransformer">
    <constructor-arg>
        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="org.example"/>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
    </constructor-arg>
</bean>

デフォルトでは、MarshallingTransformer はペイロードオブジェクトを Marshaller に渡します。ただし、ブール値の extractPayload プロパティが false に設定されている場合、Message インスタンス全体が代わりに Marshaller に渡されます。これは、Marshaller インターフェースの特定のカスタム実装に役立つ場合がありますが、通常、ペイロードは、さまざまな Marshaller 実装のいずれかに委譲する場合のマーシャリングに適したソースオブジェクトです。

XsltPayloadTransformer

XsltPayloadTransformer (Javadoc) は、拡張可能なスタイルシート言語変換 [Wikipedia] (英語) (XSLT)を使用して XML ペイロードを変換します。トランスフォーマーのコンストラクターには、リソース (Javadoc) またはテンプレート (標準 Javadoc) (英語) のいずれかのインスタンスを渡す必要があります。Templates インスタンスを渡すことで、テンプレートインスタンスの作成に使用する TransformerFactory をさらに構成できます。

UnmarshallingTransformer と同様に、XsltPayloadTransformer は Source のインスタンスに対して実際の XSLT 変換を行います。メッセージペイロードが Source のインスタンスではない場合、変換は引き続き試行されます。String および Document ペイロードは直接サポートされています。

Source へのカスタム変換を作成するには、SourceFactory (Javadoc) の実装を注入できます。

SourceFactory が明示的に設定されていない場合、XsltPayloadTransformer のプロパティはデフォルトで DomSourceFactory (Javadoc) に設定されます。

デフォルトでは、XsltPayloadTransformer は XmlPayloadMarshallingTransformer と同様に、Result (標準 Javadoc) (英語) ペイロードを持つメッセージを作成します。ResultFactory (Javadoc) または ResultTransformer (Javadoc) を提供することにより、これをカスタマイズできます。

次の例では、XSLT ペイロードトランスフォーマーとして機能する Bean を構成します。

<bean id="xsltPayloadTransformer" class="o.s.i.xml.transformer.XsltPayloadTransformer">
  <constructor-arg value="classpath:org/example/xsl/transform.xsl"/>
  <constructor-arg>
    <bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
  </constructor-arg>
</bean>

Spring Integration 3.0 以降では、コンストラクター引数を使用して、トランスフォーマーファクトリクラス名を指定できます。これは、名前空間を使用するときに transformer-factory-class 属性を使用して行うことができます。

ResultTransformer 実装の使用

MarshallingTransformer と XsltPayloadTransformer の両方で、ResultTransformer (Javadoc) を指定できます。マーシャリングまたは XSLT 変換が Result (標準 Javadoc) (英語) を返す場合、ResultTransformer を使用して Result を別の形式に変換するオプションもあります。Spring Integration は、2 つの具体的な ResultTransformer 実装を提供します。

デフォルトでは、MarshallingTransformer は常に Result (標準 Javadoc) (英語) を返します。ResultTransformer を指定することにより、返されるペイロードの型をカスタマイズできます。

XsltPayloadTransformer の動作はやや複雑です。デフォルトでは、入力ペイロードが String または Document (標準 Javadoc) (英語) のインスタンスである場合、resultTransformer プロパティは無視されます。

ただし、入力ペイロードが Source (標準 Javadoc) (英語) またはその他の型の場合、resultTransformer プロパティが適用されます。さらに、alwaysUseResultFactory プロパティを true に設定できます。これにより、指定された resultTransformer も使用されます。

詳細および例については、名前空間の構成と結果 Transformers を参照してください。

XMLTransformers のネームスペースサポート

すべての XML トランスフォーマーの名前空間サポートは、Spring Integration XML 名前空間で提供されます。このテンプレートのテンプレートは前に示しました。トランスフォーマーの名前空間サポートは、提供された入力チャネルの型に応じて、EventDrivenConsumer または PollingConsumer のいずれかのインスタンスを作成します。名前空間のサポートは、1 つの要素を使用するエンドポイントとトランスフォーマーの作成を許可することにより、XML 構成の量を減らすように設計されています。

UnmarshallingTransformer を使用する

UnmarshallingTransformer のネームスペースサポートを以下に示します。名前空間はトランスフォーマーではなくエンドポイントインスタンスを作成するため、要素内にポーラーをネストして、入力チャネルのポーリングを制御できます。次の例は、その方法を示しています。

<int-xml:unmarshalling-transformer id="defaultUnmarshaller"
    input-channel="input" output-channel="output"
    unmarshaller="unmarshaller"/>

<int-xml:unmarshalling-transformer id="unmarshallerWithPoller"
    input-channel="input" output-channel="output"
    unmarshaller="unmarshaller">
    <int:poller fixed-rate="2000"/>
<int-xml:unmarshalling-transformer/>
MarshallingTransformer を使用する

マーシャリングトランスフォーマーの名前空間サポートには、input-channeloutput-channelmarshaller への参照が必要です。オプションの result-type 属性を使用して、作成される結果の型を制御できます。有効な値は StringResult または DomResult (デフォルト)です。次の例では、マーシャリングトランスフォーマーを構成します。

<int-xml:marshalling-transformer
     input-channel="marshallingTransformerStringResultFactory"
     output-channel="output"
     marshaller="marshaller"
     result-type="StringResult" />

<int-xml:marshalling-transformer
    input-channel="marshallingTransformerWithResultTransformer"
    output-channel="output"
    marshaller="marshaller"
    result-transformer="resultTransformer" />

<bean id="resultTransformer" class="o.s.i.xml.transformer.ResultToStringTransformer"/>

提供された結果型では不十分な場合、result-factory 属性を使用して result-type 属性を設定する代わりに、ResultFactory のカスタム実装への参照を提供できます。result-type 属性と result-factory 属性は相互に排他的です。

内部的に、StringResult および DomResult の結果型は、それぞれ ResultFactory の実装(StringResultFactory (Javadoc) および DomResultFactory (Javadoc) )で表されます。
XsltPayloadTransformer を使用する

XsltPayloadTransformer のネームスペースサポートにより、Resource を渡す(Templates (標準 Javadoc) (英語) インスタンスを作成するため)か、事前に作成された Templates インスタンスを参照として渡すことができます。マーシャリングトランスフォーマーと同様に、result-factory または result-type 属性のいずれかを指定することにより、結果出力の型を制御できます。送信する前に結果を変換する必要がある場合、result-transformer 属性を使用して ResultTransformer の実装を参照できます。

result-factory または result-type 属性を指定すると、基になる XsltPayloadTransformer (Javadoc) の alwaysUseResultFactory プロパティは XsltPayloadTransformerParser (Javadoc) によって true に設定されます。

次の例では、2 つの XSLT トランスフォーマーを構成します。

<int-xml:xslt-transformer id="xsltTransformerWithResource"
    input-channel="withResourceIn" output-channel="output"
    xsl-resource="org/springframework/integration/xml/config/test.xsl"/>

<int-xml:xslt-transformer id="xsltTransformerWithTemplatesAndResultTransformer"
    input-channel="withTemplatesAndResultTransformerIn" output-channel="output"
    xsl-templates="templates"
    result-transformer="resultTransformer"/>

変換を支援するために、Message ヘッダーなどの Message データへのアクセスが必要になる場合があります。例: 特定の Message ヘッダーにアクセスし、パラメーターとしてトランスフォーマー(たとえば、transformer.setParameter(..))に渡す必要がある場合があります。Spring Integration には、次の例に示すように、これを実現する 2 つの便利な方法があります。

<int-xml:xslt-transformer id="paramHeadersCombo"
    input-channel="paramHeadersComboChannel" output-channel="output"
    xsl-resource="classpath:transformer.xslt"
    xslt-param-headers="testP*, *foo, bar, baz">

    <int-xml:xslt-param name="helloParameter" value="hello"/>
    <int-xml:xslt-param name="firstName" expression="headers.fname"/>
</int-xml:xslt-transformer>

メッセージヘッダー名がパラメーター名と 1 対 1 で一致する場合は、xslt-param-headers 属性を使用できます。その中で、単純なパターンマッチングにワイルドカードを使用できます。次の単純なパターンスタイルをサポートします: xxx*xxx*xxxxxx*yyy

<xslt-param/> 要素を使用して、個々の XSLT パラメーターを構成することもできます。その要素で、expression 属性または value 属性を設定できます。expression 属性は、Message が式評価コンテキストのルートオブジェクトである有効な SpEL 式でなければなりません。value 属性(Spring Bean の value と同様)を使用すると、単純なスカラー値を指定できます。プロパティプレースホルダー(${some.value} など)を使用することもできます。expression および value 属性を使用すると、XSLT パラメーターを Message のアクセス可能な部分およびリテラル値にマップできます。

Spring Integration 3.0 から、transformer-factory-class 属性を設定することにより、トランスフォーマファクトリクラス名を指定できるようになりました。

名前空間の構成と結果 Transformers

ResultTransformer 実装の使用での結果トランスフォーマーの使用について説明します。このセクションの例では、XML 名前空間の構成を使用して、いくつかの特別な使用例を示しています。最初に、次の例に示すように ResultTransformer を定義します。

<beans:bean id="resultToDoc" class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>

この ResultTransformer は、入力として StringResult または DOMResult を受け入れ、入力を Document に変換します。

次のように、トランスフォーマーを宣言できます。

<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
    xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"/>

受信メッセージのペイロードの型が Source である場合、最初のステップとして、Result は ResultFactory を使用して決定されます。ResultFactory を指定しなかったため、デフォルトの DomResultFactory が使用されます。つまり、変換により DomResult が生成されます。

ただし、ResultTransformer を指定したため、それが使用され、結果の Message ペイロードは型 Document になります。

指定された ResultTransformer は、String または Document ペイロードでは無視されます。受信メッセージのペイロードの型が String の場合、XSLT 変換後のペイロードは String です。同様に、受信メッセージのペイロードの型が Document の場合、XSLT 変換後のペイロードは `Document` です。

メッセージペイロードが SourceStringDocument でない場合、フォールバックオプションとして、デフォルトの SourceFactory (Javadoc) を使用して `Source` を作成しようとします。source-factory 属性を使用して SourceFactory を明示的に指定しなかったため、デフォルトの DomSourceFactory (Javadoc) が使用されます。成功すると、前の段落で説明したように、ペイロードが Source 型であるかのように XSLT 変換が実行されます。

DomSourceFactory は、DocumentFileString ペイロードからの DOMSource の作成をサポートします。

次のトランスフォーマ宣言は、値として StringResult を使用する result-type 属性を追加します。result-type は、StringResultFactory によって内部的に表されます。result-factory 属性を使用して StringResultFactory への参照を追加することもできますが、これは同じでした。次の例は、そのトランスフォーマ宣言を示しています。

<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
		xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"
		result-type="StringResult"/>

ResultFactory を使用するため、XsltPayloadTransformer クラスの alwaysUseResultFactory プロパティは暗黙的に true に設定されます。参照される ResultToDocumentTransformer が使用されます。

型 String のペイロードを変換すると、結果のペイロードは型 Document (標準 Javadoc) (英語) になります。

XsltPayloadTransformer および <xsl:output method="text"/>

<xsl:output method="text"/> は、入力ソースからテキストコンテンツのみを生成するように XSLT テンプレートに指示します。この特定のケースでは、DomResult を使用する理由はありません。基になる javax.xml.transform.Transformer の method と呼ばれる出力プロパティ (標準 Javadoc) (英語) が text を返す場合、XsltPayloadTransformer (Javadoc) は StringResult にデフォルト設定されます。この強制は、受信ペイロード型とは独立して実行されます。この動作は、<int-xml:xslt-transformer> コンポーネントの result-type 属性または result-factory 属性を設定した場合にのみ使用可能です。

XPath を使用した XML メッセージの変換

メッセージの変換に関しては、XPath は XML ペイロードを持つメッセージを変換する優れた方法です。そのためには、<xpath-transformer/> 要素を使用して XPath トランスフォーマーを定義します。

単純な XPath 変換

次のトランス構成を検討してください。

<int-xml:xpath-transformer input-channel="inputChannel" output-channel="outputChannel"
      xpath-expression="/person/@name" />

次の Message も考慮してください。

Message<?> message =
  MessageBuilder.withPayload("<person name='John Doe' age='42' married='true'/>").build();

このメッセージを "inputChannel" に送信した後、前に構成した XPath トランスフォーマーは、この XML メッセージを "John Doe" のペイロードを持つ単純な Message に変換し、すべて xpath-expression 属性で指定された単純な XPath 式に基づきます。

XPath を使用すると、抽出した要素を目的の型に簡単に変換することもできます。有効な戻り値の型は javax.xml.xpath.XPathConstants で定義され、javax.xml.xpath.XPath インターフェースで指定された変換規則に従います。

次の定数は、XPathConstants クラスによって定義されています: BOOLEANDOM_OBJECT_MODELNODENODESETNUMBERSTRING

次の例に示すように、<xpath-transformer/> 要素の evaluation-type 属性を使用して、目的の型を構成できます(2 回)。

<int-xml:xpath-transformer input-channel="numberInput" xpath-expression="/person/@age"
                           evaluation-type="NUMBER_RESULT" output-channel="output"/>

<int-xml:xpath-transformer input-channel="booleanInput"
                           xpath-expression="/person/@married = 'true'"
                           evaluation-type="BOOLEAN_RESULT" output-channel="output"/>

ノードマッパー

XPath 式によって抽出されたノードにカスタムマッピングを提供する必要がある場合、org.springframework.xml.xpath.NodeMapper の実装(Node オブジェクトをノードごとにマッピングするために XPathOperations 実装で使用されるインターフェース)への参照を提供できます。NodeMapper への参照を提供するには、次の例に示すように、node-mapper 属性を使用できます。

<int-xml:xpath-transformer input-channel="nodeMapperInput" xpath-expression="/person/@age"
                           node-mapper="testNodeMapper" output-channel="output"/>

次の例は、前述の例と連携する NodeMapper 実装を示しています。

class TestNodeMapper implements NodeMapper {
  public Object mapNode(Node node, int nodeNum) throws DOMException {
    return node.getTextContent() + "-mapped";
  }
}

XML ペイロードコンバーター

org.springframework.integration.xml.XmlPayloadConverter の実装を使用して、よりきめ細かな変換を提供することもできます。次の例は、定義方法を示しています。

<int-xml:xpath-transformer input-channel="customConverterInput"
                           output-channel="output" xpath-expression="/test/@type"
                           converter="testXmlPayloadConverter" />

次の例は、前述の例で機能する XmlPayloadConverter 実装を示しています。

class TestXmlPayloadConverter implements XmlPayloadConverter {
  public Source convertToSource(Object object) {
    throw new UnsupportedOperationException();
  }
  //
  public Node convertToNode(Object object) {
    try {
      return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
          new InputSource(new StringReader("<test type='custom'/>")));
    }
    catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }
  //
  public Document convertToDocument(Object object) {
    throw new UnsupportedOperationException();
  }
}

この参照を指定しない場合は、DefaultXmlPayloadConverter が使用されます。NodeDocumentSourceFileStringInputStreambyte[] ペイロードから変換できるため、ほとんどの場合はこれで十分です。デフォルトの実装の機能を超えて拡張する必要がある場合は、ここでこの戦略のカスタム実装への参照を提供するよりも、アップストリーム Transformer の方がおそらく優れたオプションです。

XML メッセージの分割

XPathMessageSplitter は、String または Document ペイロードのいずれかを持つメッセージをサポートします。スプリッターは、提供された XPath 式を使用して、ペイロードを複数のノードに分割します。デフォルトでは、これにより各 Node インスタンスが新しいメッセージのペイロードになります。各メッセージが Document である必要がある場合、createDocuments フラグを設定できます。String ペイロードが渡される場合、ペイロードは変換されてから分割されてから、多くの String メッセージに変換されます。XPath スプリッターは MessageHandler を実装するため、適切なエンドポイントと組み合わせて構成する必要があります(より単純な構成の代替方法については、以下の例の後の名前空間サポートの例を参照してください)。次の例では、XPathMessageSplitter を使用する Bean を構成します。

<bean id="splittingEndpoint"
      class="org.springframework.integration.endpoint.EventDrivenConsumer">
    <constructor-arg ref="orderChannel" />
    <constructor-arg>
        <bean class="org.springframework.integration.xml.splitter.XPathMessageSplitter">
            <constructor-arg value="/order/items" />
            <property name="documentBuilder" ref="customisedDocumentBuilder" />
            <property name="outputChannel" ref="orderItemsChannel" />
        </bean>
    </constructor-arg>
</bean>

XPath スプリッタ名前空間のサポートにより、次の例に示すように、入力チャネルと出力チャネルを持つメッセージエンドポイントを作成できます。

<!-- Split the order into items and create a new message for each item node -->
<int-xml:xpath-splitter id="orderItemSplitter"
                       input-channel="orderChannel"
                       output-channel="orderItemsChannel">
    <int-xml:xpath-expression expression="/order/items"/>
</int-xml:xpath-splitter>

<!-- Split the order into items, create a new document for each item-->
<int-xml:xpath-splitter id="orderItemDocumentSplitter"
                       input-channel="orderChannel"
                       output-channel="orderItemsChannel"
                       create-documents="true">
    <int-xml:xpath-expression expression="/order/items"/>
    <int:poller fixed-rate="2000"/>
</int-xml:xpath-splitter>

バージョン 4.2 以降、XPathMessageSplitter は、リクエスト payload が型 org.w3c.dom.Node でない場合、javax.xml.transform.Transformer インスタンスの outputProperties (OutputKeys.OMIT_XML_DECLARATION など)プロパティを公開します。次の例では、プロパティを定義し、output-properties プロパティで使用します。

<util:properties id="outputProperties">
	<beans:prop key="#{T (javax.xml.transform.OutputKeys).OMIT_XML_DECLARATION}">yes</beans:prop>
</util:properties>

<xpath-splitter input-channel="input"
             output-properties="outputProperties">
    <xpath-expression expression="/orders/order"/>
</xpath-splitter>

version 4.2 から、XPathMessageSplitter は iterator オプションを boolean フラグとして公開します(デフォルトは true)。これにより、ダウンストリームフローのスプリットノードの「ストリーミング」が可能になります。iterator モードを true に設定すると、各ノードは反復中に変換されます。false の場合、スプリットノードが出力チャネルに送信される前に、すべてのエントリが最初に変換されます。(違いは、「変換、送信、変換、送信」対「変換、変換、送信、送信」と考えることができます)詳細については、スプリッターを参照してください。

XPath を使用した XML メッセージのルーティング

SpEL ベースのルーターと同様に、Spring Integration は、XPath 式に基づいてメッセージをルーティングするためのサポートを提供します。これにより、入力チャネルはあるが出力チャネルはないメッセージエンドポイントを作成できます。代わりに、1 つ以上の出力チャネルが動的に決定されます。次の例は、このようなルーターを作成する方法を示しています。

<int-xml:xpath-router id="orderTypeRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/order/type"/>
</int-xml:xpath-router>
ルーターに共通の属性の概要については、共通のルーターパラメーターを参照してください。

内部的に、XPath 式は型 NODESET として評価され、チャネル名を表す List<String> に変換されます。通常、このようなリストには単一のチャンネル名が含まれます。ただし、XPath 式の結果に基づいて、XPath 式が複数の値を返す場合、XPath ルーターは受信者リストルーターの特性を引き受けることもできます。その場合、List<String> には複数のチャネル名が含まれます。その結果、メッセージはリスト内のすべてのチャネルに送信されます。

次のルーター構成に渡される XML ファイルにチャネル名を表す多くの responder サブ要素が含まれると仮定すると、メッセージはそれらのすべてのチャネルに送信されます。

<!-- route the order to all responders-->
<int-xml:xpath-router id="responderRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/request/responders"/>
</int-xml:xpath-router>

返された値がチャネル名を直接表していない場合、追加のマッピングパラメーターを指定して、返された値を実際のチャネル名にマッピングできます。たとえば、/request/responders 式の結果が 2 つの値(responderA および responderB)であるが、レスポンダー名をチャネル名に結合したくない場合、次のような追加のマッピング構成を提供できます。

<!-- route the order to all responders-->
<int-xml:xpath-router id="responderRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/request/responders"/>
    <int-xml:mapping value="responderA" channel="channelA"/>
    <int-xml:mapping value="responderB" channel="channelB"/>
</int-xml:xpath-router>

すでに記述されていたように、XPath 式のデフォルトの評価型は NODESET です。これは、単一チャネルシナリオと複数チャネルシナリオを処理するチャネル名の List<String> に変換されます。

それでも、特定の XPath 式は最初から String 型として評価される場合があります。たとえば、次の XPath 式を考えてみましょう。

name(./node())

この式は、ルートノードの名前を返します。デフォルトの評価型 NODESET が使用されている場合、例外が発生します。

これらのシナリオでは、評価型を管理できる evaluate-as-string 属性を使用できます。デフォルトでは FALSE です。ただし、これを TRUE に設定すると、String 評価型が使用されます。

XPath 1.0 は 4 つのデータ型を指定します:

  • ノードセット

  • ストリング

  • 番号

  • Boolean

XPath ルーターがオプションの evaluate-as-string 属性を使用して式を評価する場合、XPath 仕様で定義されているように、戻り値は string() 関数によって決定されます。つまり、式が複数のノードを選択した場合、最初のノードの文字列値を返します。

詳細については、以下を参照してください。

例: ルートノードの名前に基づいてルーティングする場合、次の構成を使用できます。

<int-xml:xpath-router id="xpathRouterAsString"
        input-channel="xpathStringChannel"
        evaluate-as-string="true">
    <int-xml:xpath-expression expression="name(./node())"/>
</int-xml:xpath-router>

XML ペイロードコンバーター

XPath ルーターの場合、XPath 評価の前にペイロードを変換するときに使用するコンバーターを指定することもできます。そのため、XPath ルーターは XmlPayloadConverter 戦略のカスタム実装をサポートしており、XML で xpath-router 要素を構成する場合、そのような実装への参照は converter 属性を介して提供されます。

この参照が明示的に提供されない場合、DefaultXmlPayloadConverter が使用されます。Node、Document、Source、File、String 型のペイロードから変換できるため、ほとんどの場合で十分です。そのデフォルト実装の機能を超えて拡張する必要がある場合、ほとんどの場合、ここでこの戦略のカスタム実装への参照を提供するよりも、通常、上流の Transformer がより良いオプションです。

XPath ヘッダーエンリッチャー

XPath ヘッダーエンリッチャーは、メッセージペイロードに対して XPath 式を評価し、評価の結果をメッセージヘッダーに挿入するヘッダーエンリッチャーメッセージトランスフォーマーを定義します。

以下のリストは、使用可能なすべての構成パラメーターを示しています。

<int-xml:xpath-header-enricher default-overwrite="true"    (1)
                               id=""                       (2)
                               input-channel=""            (3)
                               output-channel=""           (4)
                               should-skip-nulls="true">   (5)
    <int:poller></int:poller>                              (6)
    <int-xml:header name=""                                (7)
                    evaluation-type="STRING_RESULT"        (8)
                    header-type="int"                      (9)
                    overwrite="true"                       (10)
                    xpath-expression=""                    (11)
                    xpath-expression-ref=""/>              (12)
</int-xml:xpath-header-enricher>
1 既存のヘッダー値を上書きするかどうかのデフォルトのブール値を指定します。これは、独自の 'overwrite' 属性を提供しない子要素に対してのみ有効です。"default-overwrite" 属性を設定しない場合、指定されたヘッダー値は、同じヘッダー名を持つ既存の値を上書きしません。オプション。
2 基礎となる Bean 定義の ID。オプション。
3 このエンドポイントの受信メッセージチャネル。オプション。
4 強化されたメッセージが送信されるチャネル。オプション。
5 式の評価から返される可能性のある NULL 値をスキップするかどうかを指定します。デフォルト値は true です。null 値が対応するヘッダーの削除をトリガーする必要がある場合は、これを false に設定します。オプション。
6 ヘッダーエンリッチャーで使用するポーラー。オプション。
7 拡張するヘッダーの名前。必須です。
8XPath 評価から期待される結果型。header-type 属性を設定しなかった場合、これはヘッダー値の型です。次の値が許可されます: BOOLEAN_RESULTSTRING_RESULTNUMBER_RESULTNODE_RESULTNODE_LIST_RESULT。設定されていない場合、デフォルトで XPathEvaluationType.STRING_RESULT になります。オプション。
9 ヘッダー値型の完全修飾クラス名。XPath 評価の結果は、ConversionService によってこの型に変換されます。これにより、たとえば、NUMBER_RESULT (double)を Integer に変換できます。型はプリミティブ(int など)として宣言できますが、結果は常に同等のラッパークラス(Integer など)になります。ペイロード型変換で説明したのと同じ統合 ConversionService が変換に使用されるため、カスタムコンバーターをサービスに追加することにより、カスタム型への変換がサポートされます。オプション。
10 入力 Message にすでに存在する場合、このヘッダー値が同じ名前の既存のヘッダー値を上書きするかどうかを示すブール値。
11String としての XPath 式。この属性または xpath-expression-ref のいずれかを設定する必要がありますが、両方を設定することはできません。
12XPath 式の参照。この属性または xpath-expression のいずれかを設定する必要がありますが、両方は設定できません。

XPath フィルターの使用

このコンポーネントは、XPath ベースのメッセージフィルターを定義します。内部的に、このコンポーネントは AbstractXPathMessageSelector のインスタンスをラップする MessageFilter を使用します。

詳細については、フィルターを参照してください。

XPath フィルターを使用するには、xpath-expression 要素を宣言するか、xpath-expression-ref 属性で XPath 式を参照することにより、少なくとも XPath 式を提供する必要があります。

指定された XPath 式が boolean 値に評価される場合、それ以上の構成パラメーターは必要ありません。ただし、XPath 式が String に評価される場合、評価結果が一致する match-value 属性を設定する必要があります。

match-type には 3 つのオプションがあります。

  • exactjava.lang.String の equals に対応します。基になる実装は StringValueTestXPathMessageSelector を使用します

  • case-insensitivejava.lang.String の equals-ignore-case に対応します。基になる実装は StringValueTestXPathMessageSelector を使用します

  • regex: 操作 java.lang.String に一致します。基礎となる実装は RegexTestXPathMessageSelector を使用します

"regex" の "match-type" 値を提供する場合、match-value 属性で提供される値は有効な正規表現でなければなりません。

次の例は、xpath-filter 要素で使用可能なすべての属性を示しています。

<int-xml:xpath-filter discard-channel=""                      (1)
                      id=""                                   (2)
                      input-channel=""                        (3)
                      match-type="exact"                      (4)
                      match-value=""                          (5)
                      output-channel=""                       (6)
                      throw-exception-on-rejection="false"    (7)
                      xpath-expression-ref="">                (8)
    <int-xml:xpath-expression ... />                          (9)
    <int:poller ... />                                        (10)
</int-xml:xpath-filter>
1 拒否されたメッセージを送信するメッセージチャネル。オプション。
2 基礎となる Bean 定義の ID。オプション。
3 このエンドポイントの受信メッセージチャネル。オプション。
4XPath 評価結果と match-value の間に適用する一致の型。デフォルトは exact です。オプション。
5XPath 評価結果と照合される文字列値。この属性を設定しない場合、XPath 評価はブール値の結果を生成する必要があります。オプション。
6 フィルター条件に一致したメッセージがディスパッチされるチャネル。オプション。
7 デフォルトでは、このプロパティは false に設定され、拒否されたメッセージ(フィルター条件に一致しなかったメッセージ)は静かにドロップされます。ただし、true に設定されている場合、メッセージの拒否によりエラー状態が発生し、例外が呼び出し元にアップストリームに伝播されます。オプション。
8 評価する XPath 式インスタンスへの参照。
9 この子要素は、評価される XPath 式を設定します。この要素を含めない場合は、xpath-expression-ref 属性を設定する必要があります。また、xpath-expression 要素を 1 つだけ含めることができます。
10XPath フィルターで使用するポーラー。オプション。

#xpath SpEL 関数

Spring Integration は、バージョン 3.0 以降、XPathUtils.evaluate(…​) 静的メソッドを呼び出すビルトイン #xpath SpEL 関数を提供します。このメソッドは org.springframework.xml.xpath.XPathExpression に委譲します。次のリストは、いくつかの使用例を示しています。

<transformer expression="#xpath(payload, '/name')"/>

<filter expression="#xpath(payload, headers.xpath, 'boolean')"/>

<splitter expression="#xpath(payload, '//book', 'document_list')"/>

<router expression="#xpath(payload, '/person/@age', 'number')">
    <mapping channel="output1" value="16"/>
    <mapping channel="output2" value="45"/>
</router>

#xpath() は、XPath 評価の結果を変換するための 3 番目のオプションのパラメーターもサポートします。文字列定数(stringbooleannumbernodenode_listdocument_list)または org.springframework.xml.xpath.NodeMapper インスタンスのいずれかです。デフォルトでは、#xpath SpEL 関数は XPath 評価の String 表現を返します。

#xpath SpEL 機能を有効にするには、spring-integration-xml.jar をクラスパスに追加できます。Spring Integration XML 名前空間からコンポーネントを宣言する必要はありません。

詳細については、" ` Spring 式言語 (SpEL)" を参照してください。

XML 検証フィルター

XML 検証フィルターを使用すると、提供されたスキーマインスタンスに対して受信メッセージを検証できます。次のスキーマ型がサポートされています。

検証に失敗したメッセージは、静かにドロップするか、定義可能な discard-channel に転送できます。さらに、検証が失敗した場合に Exception をスローするようにこのフィルターを構成できます。

以下のリストは、使用可能なすべての構成パラメーターを示しています。

<int-xml:validating-filter discard-channel=""                    (1)
                           id=""                                 (2)
                           input-channel=""                      (3)
                           output-channel=""                     (4)
                           schema-location=""                    (5)
                           schema-type="xml-schema"              (6)
                           throw-exception-on-rejection="false"  (7)
                           xml-converter=""                      (8)
                           xml-validator="">                     (9)
    <int:poller .../>                                            (10)
</int-xml:validating-filter>
1 拒否されたメッセージを送信するメッセージチャネル。オプション。
2 基礎となる Bean 定義の ID。オプション。
3 このエンドポイントの受信メッセージチャネル。オプション。
4 受け入れられたメッセージを送信するメッセージチャネル。オプション。
5 メッセージのペイロードを検証するスキーマの場所を設定します。内部で org.springframework.core.io.Resource インターフェースを使用します。この属性または xml-validator 属性を設定できますが、両方は設定できません。オプション。
6 スキーマ型を設定します。xml-schema または relax-ng のいずれかです。オプション。設定されていない場合、デフォルトで xml-schema になり、内部で org.springframework.xml.validation.XmlValidatorFactory#SCHEMA_W3C_XML に変換されます。
7true の場合、提供されたメッセージのペイロードの検証が失敗すると、MessageRejectedException がスローされます。設定しない場合、デフォルトは false です。オプション。
8 カスタム org.springframework.integration.xml.XmlPayloadConverter 戦略への参照。オプション。
9 カスタム sorg.springframework.xml.validation.XmlValidator 戦略への参照。この属性または schema-location 属性を設定できますが、両方は設定できません。オプション。
10XPath フィルターで使用するポーラー。オプション。