|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
使用 XPath 转换 XML 消息
当涉及消息转换时,XPath 是一种转换具有 XML 有效负载的消息的绝佳方式。
你可以通过定义 XPath 转换器来实现,使用 <xpath-transformer/> 元素。
简单 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可能比在此处提供对此策略的自定义实现的引用是更好的选择。