名稱空間支援

Spring Integration XML 模組中的所有元件都提供名稱空間支援。要啟用名稱空間支援,您需要匯入 Spring Integration XML 模組的 schema。以下示例顯示了典型的設定

<?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.XPathExpressionFactoryXPathExpression。建立 XPath 表示式時,會使用 classpath 中可用的最佳 XPath 實現(JAXP 1.3+ 或 Jaxen,優先使用 JAXP)。

在內部,Spring Integration 使用 Spring Web Services 專案(www.spring.io/spring-ws)提供的 XPath 功能。具體來說,我們使用 Spring Web Services XML 模組 (spring-xml-x.x.x.jar)。要獲得更深入的瞭解,請參閱相應的文件 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>
1 定義一個 XPath 表示式。必需。
2 底層 bean 定義的識別符號。它是 org.springframework.xml.xpath.XPathExpression 的一個例項。可選。
3 引用包含名稱空間的 Map。Map 的鍵定義名稱空間字首,Map 的值設定名稱空間 URI。同時指定此屬性和 map 元素或 ns-prefixns-uri 屬性是無效的。可選。
4 允許您直接將名稱空間字首作為屬性設定在 XPath 表示式元素上。如果您設定了 ns-prefix,則也必須設定 ns-uri 屬性。可選。
5 允許您直接將名稱空間 URI 作為屬性設定在 XPath 表示式元素上。如果您設定了 ns-uri,則也必須設定 ns-prefix 屬性。可選。
6 定義一個包含名稱空間的 Map。只允許一個 map 子元素。Map 的鍵定義名稱空間字首,Map 的值設定名稱空間 URI。同時指定此元素和 map 屬性或設定 ns-prefixns-uri 屬性是無效的。可選。

為 XPath 表示式提供名稱空間(可選)

對於 XPath 表示式元素,您可以將名稱空間資訊作為配置引數提供。您可以使用以下選項之一定義名稱空間

  • 使用 namespace-map 屬性引用一個 Map

  • 使用 map 子元素提供一個名稱空間 Map

  • 指定 ns-prefixns-uri 屬性

所有這三個選項是互斥的。只能設定其中一個選項。

以下示例展示了幾種使用 XPath 表示式的不同方式,包括設定 XML 名稱空間 前面提到的 選項

<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 文件(代表兩個圖書訂單)

<?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)在這種情況下會失敗。

為了解決此問題,您必須提供名稱空間字首和名稱空間 URI,可以透過設定 ns-prefixns-uri 屬性,或者透過設定 namespace-map 屬性。名稱空間 URI 必須與您的 XML 文件中宣告的名稱空間匹配。在前面的示例中,它是 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 是真正重要的資訊,而不是字首。Jaxen 很好地總結了這一點

在 XPath 1.0 中,所有不帶字首的名稱都是非限定的。XPath 表示式中使用的字首與被查詢文件中使用的字首不必相同。只需要名稱空間 URI 匹配即可,字首無需匹配。