第 32 章 XPath 语言

摘要

当处理 XML 消息时,XPath 语言允许您选择消息的一部分,方法是通过指定适用于消息的 Document Object Model(DOM)的 XPath 表达式。您还可以定义 XPath predicates 来测试元素或属性的内容。

32.1. Java DSL

基本表达式

您可以使用 xpath("Expression") 来评估当前交换中的 XPath 表达式(其中 XPath 表达式被应用于当前消息的正文)。xpath() 表达式的结果是一个 XML 节点(如果有多个节点匹配,则为节点集)。

例如,要从当前 In 消息正文中提取 /person/name 元素的内容,并使用它来设置名为 user 的标头,您可以定义一个类似如下的路由:

from("queue:foo")
    .setHeader("user", xpath("/person/name/text()"))
    .to("direct:tie");

除了将 xpath() 指定为 setHeader() 的参数外,您可以使用 fluent builder xpath() command>_<-对 example:

from("queue:foo")
    .setHeader("user").xpath("/person/name/text()")
    .to("direct:tie");

如果要将结果转换为特定的类型,请将结果类型指定为 xpath() 的第二个参数。例如,要明确指定结果类型是 String

xpath("/person/name/text()", String.class)

命名空间

通常,XML 元素属于一个 schema,它通过命名空间 URI 进行标识。当处理诸如此类文档时,需要将命名空间 URI 与前缀关联,以便您可以在 XPath 表达式中明确识别元素名称。Apache Camel 提供帮助程序类 org.apache.camel.builder.xml.Namespaces,用于定义命名空间和前缀之间的关联。

例如,要将前缀 cust 与命名空间 http://acme.com/customer/record 关联,然后提取元素的内容 /cust:person/cust:name,您可以定义一个类似如下的路由:

import org.apache.camel.builder.xml.Namespaces;
...
Namespaces ns = new Namespaces("cust", "http://acme.com/customer/record");

from("queue:foo")
    .setHeader("user", xpath("/cust:person/cust:name/text()", ns))
    .to("direct:tie");

您可以通过传递 Namespaces 对象 ns 作为额外参数,将命名空间定义提供给 xpath() 表达式构建器。如果需要定义多个命名空间,请使用 Namespace.add() 方法,如下所示:

import org.apache.camel.builder.xml.Namespaces;
...
Namespaces ns = new Namespaces("cust", "http://acme.com/customer/record");
ns.add("inv", "http://acme.com/invoice");
ns.add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

如果需要指定结果类型 并定义 命名空间,您可以使用三参数形式 xpath(),如下所示:

xpath("/person/name/text()", String.class, ns)

审计命名空间

使用 XPath 表达式时,可能会出现最频繁的问题之一是命名空间在传入消息中出现不匹配的情况和 XPath 表达式中使用的命名空间。为了帮助您排除此类问题,XPath 语言支持 选项将所有命名空间从所有传入消息转储到系统日志中。

要在 INFO 日志级别启用命名空间日志记录,请在 Java DSL 中启用 logNamespaces 选项,如下所示:

xpath("/foo:person/@id", String.class).logNamespaces()

或者,您也可以将日志记录系统配置为在 org.apache.camel.builder.xml.XPathBuilder 日志记录器上启用 MERGE 级别日志记录。

启用命名空间日志记录后,您会看到如下日志消息,以了解每个处理的消息:

2012-01-16 13:23:45,878 [stSaxonWithFlag] INFO  XPathBuilder  -
Namespaces discovered in message: {xmlns:a=[http://apache.org/camel],
DEFAULT=[http://apache.org/default],
xmlns:b=[http://apache.org/camelA, http://apache.org/camelB]}