使用 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
可能比在這裡提供此策略的自定義實現引用更好的選擇。