命名空间支持
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.XPathExpressionFactory
的 XPathExpression
。创建 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-prefix 和 ns-uri 属性是无效的。可选。 |
4 | 允许您直接将命名空间前缀作为属性设置在 XPath 表达式元素上。如果您设置了 ns-prefix ,则也必须设置 ns-uri 属性。可选。 |
5 | 允许您直接将命名空间 URI 作为属性设置在 XPath 表达式元素上。如果您设置了 ns-uri ,则也必须设置 ns-prefix 属性。可选。 |
6 | 定义一个包含命名空间的 Map。只允许一个 map 子元素。Map 的键定义命名空间前缀,Map 的值设置命名空间 URI。同时指定此元素和 map 属性或设置 ns-prefix 和 ns-uri 属性是无效的。可选。 |
为 XPath 表达式提供命名空间(可选)
对于 XPath 表达式元素,您可以将命名空间信息作为配置参数提供。您可以使用以下选项之一定义命名空间
-
使用
namespace-map
属性引用一个 Map -
使用
map
子元素提供一个命名空间 Map -
指定
ns-prefix
和ns-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-prefix
和 ns-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 匹配即可,前缀无需匹配。