SI <int-xml:xpath-filter>行为

时间:2015-10-27 20:22:49

标签: xpath spring-integration

我有一个场景,我根据xpath值过滤xml有效负载。

<int:channel id="documentReceiptFilterChannel" />
<int:chain input-channel="documentReceiptFilterChannel" output-channel="nullChannel">
    <!-- Filter to discard message if <statusCode> value is 'EMLOK' -->
    <int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$" discard-channel="nullChannel">
        <int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
    </int-xml:xpath-filter>
    <int:service-activator expression="@opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + @opsExceptionUtils.createOPSExceptionInstance(#root))" />
</int:chain>

以下是有效载荷:

<?xml version="1.0" encoding="UTF-8"?>
<GetDocumentReceiptReply xmlns="http://example.org"
                                xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <mergeReceiptDeliveryStatus>
      <statusCode>EMLOK</statusCode>
   </mergeReceiptDeliveryStatus>
</GetDocumentReceiptReply>

我的要求是当<statusCode>EMLOK</statusCode>元素可用时,丢弃该消息,因此nullChannel被称为discard-channel。 但是还有其他值,继续进行链中的下一步并进行错误记录 - <int:service-activator expression="@opsLogger.logError()

只要有效负载中存在<statusCode>元素,上述设置就可以正常工作。但不适用于以下情况:

  1. <statusCode></statusCode>
  2. <statusCode/>
  3. <statusCode>缺失
  4. 或任何其他xml有效负载
  5. 为了摆脱命名空间问题,xpath表达式形成为<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />。 xpath值与正则表达式match-type="regex" match-value="^(?!\bEMLOK\b).*$"匹配(对于值!='EMLOK')。

    <int-xml:xpath-expression />评估失败后会发生什么?

    我唯一的要求是,如果存在<statusCode>EMLOK</statusCode>,则丢弃该消息,否则为其他所有消息,在日志文件中记录错误。 (而不是抛出将传播到错误通道的异常)。

1 个答案:

答案 0 :(得分:0)

您可以编写AbstractXPathMessageSelector的自定义子类并委托给BooleanTestXPathMessageSelectorRegexTestXPathMessageSelector,或者只使用2个过滤器...

<int:chain input-channel="documentReceiptFilterChannel" output-channel="errors">
    <int-xml:xpath-filter discard-channel="errors">
        <int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
    </int-xml:xpath-filter>
    <int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$">
        <int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
    </int-xml:xpath-filter>
</int:chain>

<int:service-activator 
    expression="@opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + @opsExceptionUtils.createOPSExceptionInstance(#root))" />

请注意,您不需要丢弃nullChannel - 只是省略丢弃渠道会导致丢弃。通过第二个过滤器的消息将转到链的输出通道。

自定义选择器会更高效,因为只需要转换到节点一次。