I made a change in the blogger configuration to ease the later work when blogging. It is possible that older entries are not correctly formatted.

Friday, 12 July 2013

Axiom - XML Processing for Axis and others

I have been taking a look at the Apache Axis2 Web Service framework. Reading the documentation, I was reminded of the Axiom framework used for the processing of XML. Therefore, I will gather here a few informations which I find useful. These info come partially from quickstart-samples. The example are changed a little to be adapted to my way of thinking. This is also a documentation for me.


In addition to be used to process XML efficiently, Axiom can be used to process MTOM messages which are used in SOAP to transport binary data.
Again on the quickstart-samples page, there are some examples. But I will use a separate POST for this.


How to retrieve child elements from root:

public void processXmlFile(File file, String namespace, String elementName) throws IOException, OMException {
// initialize the file input stream to be closed in this method
InputStream in = new FileInputStream(file);
// get the root element
OMElement root = OMXMLBuilderFactory.createOMBuilder(in).getDocumentElement();

// Process the content of the file
OMElement element = root.getFirstChildWithName(
new QName("-http://maven.apache.org/POM/4.0.0", "url"));
if (element == null) {
System.out.println("No <"+elementName+"> element found");
} else {
System.out.println(elementName" = " + element.getText());
}

// Because Axiom uses deferred parsing, the stream must be closed AFTER
// processing the document (unless OMElement#build() is called)
in.close();
}

Schema validation

How to perform partial schema validation (from quickstart-samples).

public void validate(InputStream in, URL schemaUrl) throws Exception {
  SOAPModelBuilder builder = OMXMLBuilderFactory.createSOAPModelBuilder(in, "UTF-8");
  SOAPEnvelope envelope = builder.getSOAPEnvelope();
  OMElement bodyContent = envelope.getBody().getFirstElement();
  SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  Schema schema = schemaFactory.newSchema(schemaUrl);
  Validator validator = schema.newValidator();
  validator.validate(bodyContent.getSAXSource(true));
}

quickstart-samples presents also a way to do it with a DOMSource instead of the SAXSource.


Perform on chunks of an XML Document


Often it is useful to perform just on a particular chunk of the XML document.

public interface FragmentProcessor {

    public QName getTagName();

    public void processFragment(OEMElement);

}

  public void processFragments(InputStream in, FragmentProcessor fragmentProcessor) throws XMLStreamException {
    // Create an XMLStreamReader without building the object model
    XMLStreamReader reader =
       OMXMLBuilderFactory.createOMBuilder(in).getDocument().getXMLStreamReader(false);
    QName tagName = fragmentProcessor.getTagName();
    while (reader.hasNext()) {
       if (reader.getEventType() == XMLStreamReader.START_ELEMENT &&
          reader.getName().equals(tagName)) {
             OMElement element =
                OMXMLBuilderFactory.createStAXOMBuilder(reader).getDocumentElement();
             // Make sure that all events belonging to the element are consumed so that
             // that the XMLStreamReader points to a well defined location (namely the
             // event immediately following the END_ELEMENT event).
             element.build();
             // Now process the element.
             fragmentProcessor.processFragment(element);
          } else {
             reader.next();
          }
       }
   }