You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

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>
    <!-- use the same version as your Camel core 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") // CountingHandler implements org.xml.sax.ContentHandler or extends org.xml.sax.helpers.DefaultHandler
  .process(new Processor() {
    @Override public void process(Exchange exchange) throws Exception {
        CountingHandler handler = exchange.getIn().getBody(CountingHandler.class);
        // do some great work with the handler
    }
  });

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).

  • No labels