Transforming XML Messages with XPath
说到消息转换,XPath 是一种转换具有 XML 有效负载的消息的好方法。可以通过使用 <xpath-transformer/>
元素定义 XPath 转换器来实现。
When it comes to message transformation, XPath is a great way to transform messages that have XML payloads.
You can do so by defining XPath transformers with the <xpath-transformer/>
element.
Simple XPath Transformation
考虑以下转换器配置:
Consider following transformer configuration:
<int-xml:xpath-transformer input-channel="inputChannel" output-channel="outputChannel"
xpath-expression="/person/@name" />
还需要考虑以下 Message
:
Also consider the following Message
:
Message<?> message =
MessageBuilder.withPayload("<person name='John Doe' age='42' married='true'/>").build();
将此消息发送到 'inputChannel' 后,先前配置的 XPath 转换器会将此 XML 消息转换为带有有效负载 'John Doe' 的简单 Message
,所有这些都基于 xpath-expression
属性中指定的简单 XPath 表达式。
After sending this message to the 'inputChannel', the XPath transformer configured earlier transforms this XML Message to a simple Message
with a payload of 'John Doe', all based on the simple XPath Expression specified in the xpath-expression
attribute.
XPath 还允许你对提取的元素执行简单转换以获得所需类型。在 javax.xml.xpath.XPathConstants
中定义了有效的返回类型,且遵循了 javax.xml.xpath.XPath
接口指定的转换规则。
XPath also lets you perform simple conversion of an extracted element to a desired type.
Valid return types are defined in javax.xml.xpath.XPathConstants
and follow the conversion rules specified by the javax.xml.xpath.XPath
interface.
XPathConstants
类定义了以下常量:BOOLEAN
、DOM_OBJECT_MODEL
、NODE
、NODESET
、NUMBER
和 STRING
。
The following constants are defined by the XPathConstants
class: BOOLEAN
, DOM_OBJECT_MODEL
, NODE
, NODESET
, NUMBER
, and STRING
.
你可以通过使用 <xpath-transformer/>
元素的 evaluation-type
属性配置所需的类型,如以下示例所示(两次):
You can configure the desired type by using the evaluation-type
attribute of the <xpath-transformer/>
element, as the following example shows (twice):
<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"/>
Node Mappers
如果你需要为 XPath 表达式提取的节点提供自定义映射,则可以提供 org.springframework.xml.xpath.NodeMapper
(一个由 XPathOperations
实现用于针对每个节点映射 Node
对象的接口)实现的引用。若要提供对 NodeMapper
的引用,你可以使用 node-mapper
属性,如以下示例所示:
If you need to provide custom mapping for the node extracted by the XPath expression, you can provide a reference to the implementation of the org.springframework.xml.xpath.NodeMapper
(an interface used by XPathOperations
implementations for mapping Node
objects on a per-node basis).
To provide a reference to a NodeMapper
, you can use the node-mapper
attribute, as the following example shows:
<int-xml:xpath-transformer input-channel="nodeMapperInput" xpath-expression="/person/@age"
node-mapper="testNodeMapper" output-channel="output"/>
以下示例展示了与前面示例一起使用的 NodeMapper
实现:
The following example shows a NodeMapper
implementation that works with the preceding example:
class TestNodeMapper implements NodeMapper {
public Object mapNode(Node node, int nodeNum) throws DOMException {
return node.getTextContent() + "-mapped";
}
}
XML Payload Converter
你也可以使用 org.springframework.integration.xml.XmlPayloadConverter
实现提供更精细的转换。以下示例展示了如何定义一个:
You can also use an implementation of the org.springframework.integration.xml.XmlPayloadConverter
to provide more granular transformation.
The following example shows how to define one:
<int-xml:xpath-transformer input-channel="customConverterInput"
output-channel="output" xpath-expression="/test/@type"
converter="testXmlPayloadConverter" />
以下示例展示了与前面示例一起使用的 XmlPayloadConverter
实现:
The following example shows an XmlPayloadConverter
implementation that works with the preceding example:
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
。在大多数情况下,它就足够了,因为它可以从 Node
、 Document
、 Source
、 File
、 String
、 InputStream`和 `byte[]
有效负载进行转换。如果您需要超出该默认实现的功能,那么上游 Transformer
可能比在此处提供对该策略的自定义实现的引用更好的选择。
If you do not provide this reference, the DefaultXmlPayloadConverter
is used.
It should suffice in most cases, because it can convert from Node
, Document
, Source
, File
, String
, InputStream
, and byte[]
payloads.
If you need to extend beyond the capabilities of that default implementation, an upstream Transformer
is probably a better option than providing a reference to a custom implementation of this strategy here.