XML Tokenize
Since Camel 2.14
The XML Tokenize language (xtokenize) is a tokenizer specifically designed for XML documents. Unlike the conventional Tokenize language, which is primarily a text-based tokenizer, XML Tokenize uses a StAX parser to interpret the XML structure while producing tokens.
The conventional Tokenize language also provides an xml option for XML-aware tokenization (xml=true). This should not be confused with XML Tokenize: xtokenize uses different tokenization semantics and is intended for different use cases.
Use xtokenize when XML structure or namespaces are important, or when you want a tokenizer specifically designed for XML documents. Use the conventional Tokenize language when you primarily need text-based tokenization and XML awareness is sufficient for your use case.
Maven users will need to add the following dependency to their pom.xml for this language:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stax</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency> XML Tokenizer Options
The XML Tokenize language supports the following options which are listed below.
| Name | Default | Java Type | Description |
|---|---|---|---|
|
| The extraction mode. The available extraction modes are: i - injecting the contextual namespace bindings into the extracted token (default), w - wrapping the extracted token in its ancestor context, u - unwrapping the extracted token to its child content, t - extracting the text content of the specified element. Enum values:
| |
| To group N parts together. | ||
| Reference to a org.apache.camel.support.builder.Namespaces bean in the registry to use for the XML Namespaces of prefix to uri mappings. | ||
| Source to use, instead of message body. You can prefix with variable:, header:, or property: to specify kind of source. Otherwise, the source is assumed to be a variable. Use empty or null to use default source, which is the message body. | ||
| The class of the result type (type from output). | ||
|
| Whether to trim the source code to remove leading and trailing whitespaces and line breaks. |
Namespaces
The XML Tokenize language is namespace aware, so a tokenized element can be selected by its prefix. The prefix to URI mappings can be declared inline, or shared across several expressions by registering a org.apache.camel.support.builder.Namespaces bean and referring to it with the namespacesRef option:
-
XML
-
YAML
<camel xmlns="http://camel.apache.org/schema/xml-io">
<bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
<properties>
<property key="namespaces[c]" value="http://acme.com/cheese"/>
</properties>
</bean>
<route>
<from uri="file:inbox"/>
<split>
<xtokenize namespacesRef="myNamespaces">//c:order</xtokenize>
<to uri="mock:result"/>
</split>
</route>
</camel> - beans:
- name: myNamespaces
type: org.apache.camel.support.builder.Namespaces
properties:
namespaces[c]: "http://acme.com/cheese"
- route:
from:
uri: "file:inbox"
steps:
- split:
expression:
xtokenize:
expression: "//c:order"
namespacesRef: "myNamespaces"
steps:
- to: "mock:result" Each prefix is configured as a namespaces[prefix] property on the bean, with the namespace URI as the value.
If the expression declares namespaces inline as well, then the inline namespaces win and namespacesRef is ignored.
Example
Suppose the input XML contains multiple orders:
<?xml version="1.0" encoding="UTF-8"?>
<orders xmlns="urn:shop">
<order>
<id>1001</id>
<customer>John</customer>
</order>
<order>
<id>1002</id>
<customer>Jane</customer>
</order>
</orders> The XML Tokenize language can be used with the Split EIP to split the document into one message for each order element.
-
Java
-
XML
-
YAML
var ns = new org.apache.camel.support.builder.Namespaces("shop", "urn:shop");
from("direct:start")
.split()
.xtokenize("//shop:order", 'i', ns)
.streaming()
.to("mock:order"); <route>
<from uri="direct:start"/>
<split streaming="true">
<xtokenize>//shop:order
<namespace key="shop" value="urn:shop"/>
</xtokenize>
<to uri="mock:order"/>
</split>
</route> - route:
from:
uri: 'direct:start'
steps:
- split:
streaming: 'true'
expression:
xtokenize:
expression: '//shop:order'
namespace:
- key: shop
value: 'urn:shop'
steps:
- to:
uri: 'mock:order' The Split EIP produces two messages. The body of the first message is:
<order xmlns="urn:shop">
<id>1001</id>
<customer>John</customer>
</order> The body of the second message is:
<order xmlns="urn:shop">
<id>1002</id>
<customer>Jane</customer>
</order> The shop namespace is mapped to urn:shop, allowing the XPath expression //shop:order to identify the namespaced order elements.
See the Split EIP for more examples.