2

给定一个应该提取 XML 消息的某些内部部分的 Camel 路由,从中创建一个新消息,然后将其传递。

 from(SUB_EXTRACT_XML)
   .setExchangePattern(ExchangePattern.InOut)
   .setBody().xpath("//mmsg:MyMessage/mmsg:AnyPayload/*", namespaces) 
   .setBody().simple("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n${in.body}")
   .to(...)

对于像这样的正确输入消息(“嵌入”xml 消息由 xs:any 在模式中定义),它正在工作,因为消息是我期望的:

<mmsg:MyMessage>
  <mmsg:RandomTags/>
   ...
   <mmsg:AnyPayload> <!-- xs:any in xsd -->
     <some><xml/><here/></some>
   </mmsg:AnyPayload>
</mmsg:MyMessage>

鉴于 XML 消息存在一些问题,例如缺少 mmsg:AnyPayload 标记,因此 XPATH 无法完成其工作:

<mmsg:MyMessage>
  <mmsg:RandomTags/>
   ...
   <some><xml/><here/></some>
</mmsg:MyMessage>

XPATH 将无法提取数据并传递整个 XML 消息(包括 mmsg:MyMessage),这不是预期的。我宁愿在这个阶段抛出一些异常。

问题:

有没有办法检查 xpath 表达式是否真的找到了路由后面引用的元素,或者它是否未能提取给定的元素?

我知道我之前可以对消息进行一些模式验证并拒绝垃圾消息,但是有什么方法可以查看 XPath 表达式是否失败?

4

1 回答 1

0

一个解决方案是choice()在这样的路由中使用 DSL:

 from(SUB_EXTRACT_XML)
   .setExchangePattern(ExchangePattern.InOut)
   .choice()
        .when(xpath("//mmsg:MyMessage/mmsg:AnyPayload", namespaces))
            .setHeader("Status", "OK") // just for another example how to transmit some variable between two routes 
            .setBody().simple("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n${in.body}")
            .endChoice()
        .otherwise()
            .log(LoggingLevel.ERROR, "LoggerName", "Error message; Stop the processing")
            .stop()
        .endChoice()
    .end()
   // Just to show the headers are following the route... 
   .to("DIRECT_GO_FORWARD"); 



 from("DIRECT_GO_FORWARD")
   .setExchangePattern(ExchangePattern.InOut)
   .choice()
        .when(header("Status").isEqualTo("OK"))
            .bean(new SampleProcessor())

        ...
    .end()
    ...
    .to("...");

第二条路线只是为了表明您可以使用第一条路线中设置的标头(以及正文)。

于 2014-08-06T19:43:52.640 回答