使用 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 消息转换为一个简单的 Message
,其负载为“John Doe”,所有这些都基于在 xpath-expression
属性中指定的简单 XPath 表达式。
XPath 还允许您对提取的元素执行简单的类型转换。有效返回值在 javax.xml.xpath.XPathConstants
中定义,并遵循 javax.xml.xpath.XPath
接口指定的转换规则。
XPathConstants
类定义了以下常量:BOOLEAN
、DOM_OBJECT_MODEL
、NODE
、NODESET
、NUMBER
和 STRING
。
您可以使用 <xpath-transformer/>
元素的 evaluation-type
属性配置所需的类型,如下面的示例所示(两次)
<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
实现的引用(一个由 XPathOperations
实现用于在每个节点的基础上映射 Node
对象的接口)。要提供对 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
。它在大多数情况下应该足够,因为它可以从 Node
、Document
、Source
、File
、String
、InputStream
和 byte[]
负载进行转换。如果您需要扩展默认实现的功能,则使用上游 Transformer
可能比在此处提供对该策略的自定义实现的引用更好。