在Camel中使用XPath提取xml

时间:2018-03-20 10:13:56

标签: xpath apache-camel

我的XML结构类似于下面的示例,它存储在Camel头中作为String:

<list>
   <library>
      <name>xxx</name>
      <address>
         <line1>aaa</line1>
         <line2>bbb</line2>
         <line3>ccc</line3>
      </address>
   </library>
   <book>
      <author>
         <name>John</name>
         <number>4324234</number>
      </author>
      <title>New Book</title>
      <isbn>dsdaassda</isbn>
   </book>
   <book>...</book>
   <book>...</book>
</list>

我想将库元素提取到另一个Camel头

   <library>
      <name>xxx</name>
      <address>
         <line1>aaa</line1>
         <line2>bbb</line2>
         <line3>ccc</line3>
      </address>
   </library>

如何使用Camel Java DSL实现这一目标?

(我的主要困惑是将XPath应用于交换标题项而不是正文)

4 个答案:

答案 0 :(得分:1)

这应该有效:

.xpath("[your XPath expression]", "[the name of the header to select from]")

您的用例可以像这样完成

from("direct:input")
    .setHeader("newHeader").xpath("[your XPath]", "[xmlHeader]")
    .to("...");

您也可以在Camel docs部分Using XPath on Headers中找到。

例如,在文件底部的路径中使用此Camel unit test

答案 1 :(得分:0)

试试这个。

@Override
public void configure() throws Exception {
    XPathExpression xPathExpression = new XPathExpression();
    xPathExpression.setHeaderName("completexml"); //assuming the header name of the xml as completexml
    xPathExpression.setExpression("/list/library");

    from("direct:abc")
         .setHeader("OriginalBody", simple("${body}")) //get original body
         .split(xPathExpression) //split according to xPathExpression
         .setHeader("library", simple("${body}")) //set new header with only library element
         .setBody(simple("${header.OriginalBody}")) //set the original body back
         //.log("${header.completexml}")
         //.log("${header.library}")
         //.log("${body}")
        ;
}

根据答案here,我们可以为xpath提供第二个参数,类型为String。但是在最新版本中,我没有在xpath中看到任何这样的方法,它将第二个参数作为String。可能是在较新版本中删除。

我正在做的是将原始主体存储在标题中(因为在拆分后,原始主体被拆分的结果替换),然后替换它。

答案 2 :(得分:0)

这是JUnit测试的一个工作示例:

.setHeader("XNODE").xpath("/list/library", NodeList.class)

Оutputlog:

.setBody().xpath("/list/library", NodeList.class)

因此,对于标题,您需要一个表达式:

soup = BeautifulSoup(example_html_str, "lxml")
first_paragraph = soup.find_all("p")[0]
second_paragraph = soup.find_all("p")[1]
another_paragraph = soup.find_all("p")[0]
first_paragraph is second_paragraph
# is False
first_paragraph is another_paragraph
# is True

和身体:

let blueLocation1 = CLLocationCoordinate2D(latitude: lat1, longitude: lon1)       

let blueLocation2 = CLLocationCoordinate2D(latitude: lat2, longitude: lon2)

let routeLine = MKPolyline(coordinates:[blueLocation1,blueLocation2], count:2)

self.mapView.add(routeLine)

答案 3 :(得分:0)

你可以这样做:

.setHeader("yourHeaderName", xpath("//*[local-name()='library']").stringResult())

所以你将拥有工作的库结构