StAX Component
The StAX component allows messages to be process through a SAX ContentHandler.
The implementation convert a SAX ContentHanler to a XMLStreamReader.
Another great feature of this component is to allow to iterate over JAXB records using StAX.
Maven users will need to add the following dependency to their pom.xml for this component:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-StAX</artifactId>
<version>x.x.x</version>
</dependency>
URI format
stax:content-handler-class
example:
stax:org.superbiz.FooContentHandler
Converter
Some converters are provided by the component.
It allows you to convert a GenericFile or a File to a SAXSource, and a GenericFile or a String (representing a file path) to either a XMLStreamReader or a XMLEventReader.
Usage of a content handler as StAX parser
The message body after the handling is the handler itself.
Here an example:
from("file:target/in")
.to("StAX:org.superbiz.handler.CountingHandler") .process(new Processor() {
@Override public void process(Exchange exchange) throws Exception {
CountingHandler handler = exchange.getIn().getBody(CountingHandler.class);
}
});
Iterate over a collection using JAXB and StAX
First we suppose you have JAXB objects.
For instance a list of records in a wrapper object:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "records")
public class Records {
@XmlElement(required = true)
protected List<Record> record;
public List<Record> getRecord() {
if (record == null) {
record = new ArrayList<Record>();
}
return record;
}
}
and
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "record", propOrder = { "key", "value" })
public class Record {
@XmlAttribute(required = true)
protected String key;
@XmlAttribute(required = true)
protected String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Then you get a XML file to process:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<records>
<record value="v0" key="0"/>
<record value="v1" key="1"/>
<record value="v2" key="2"/>
<record value="v3" key="3"/>
<record value="v4" key="4"/>
<record value="v5" key="5"/>
</record>
The StAX component provides an iterator call org.apache.camel.stax.StAXJAXBIteratorExpression which allows you
to iterate through this collection with the camel splitter:
from("file:target/in")
.setBody(header(Exchange.FILE_PATH))
.split(new StAXJAXBIteratorExpression<Record>(Record.class))
.to("mock:records");
The body will be the constructor parameter class (Record in the snippet).
Note: depending on the first component you use to get your xml tree you can need to force the convertion of your body
to a known format (SAXSource, XMLStreamReader, ...) to avoid to read all the file (which is implicitely the default).