7/21/08


Java and XML: XML binding

JAXB

XMLBeans

JiBX

7/15/08


Apache AXIS

Simple invoke standard Version web service via URLConnection:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

public class Main {

public static void main(String[] args) throws Exception {

HttpURLConnection httpurlconnection = null;
String HostUrl = "localhost";
String SoapActionUrl = "http://localhost:8080/axis/services/Version";

URL url = new URL(SoapActionUrl);
URLConnection urlconnection = url.openConnection();
httpurlconnection = (HttpURLConnection) urlconnection;

StringBuffer stringbuffer = new StringBuffer();

stringbuffer.append("<SOAP-ENV:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
stringbuffer.append("<SOAP-ENV:Body>");
stringbuffer.append("<getVersion>");
stringbuffer.append("</getVersion></SOAP-ENV:Body></SOAP-ENV:Envelope>");

byte abyte0[] = stringbuffer.toString().getBytes();
httpurlconnection.addRequestProperty("Host", HostUrl);
httpurlconnection.addRequestProperty("Content-Length", String.valueOf(abyte0.length));
httpurlconnection.addRequestProperty("Content-Type", "text/xml; charset=UTF-8");
httpurlconnection.addRequestProperty("SOAPAction", SoapActionUrl);
httpurlconnection.setInstanceFollowRedirects(true);

httpurlconnection.setRequestMethod("POST");
httpurlconnection.setDoOutput(true);
httpurlconnection.setDoInput(true);

OutputStream outputstream = httpurlconnection.getOutputStream();
outputstream.write(abyte0);
outputstream.close();

System.out.println(httpurlconnection.getResponseMessage());

InputStreamReader inputstreamreader = new InputStreamReader(httpurlconnection.getInputStream());
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
StringBuffer stringbuffer1 = new StringBuffer();
String s3;
while ((s3 = bufferedreader.readLine()) != null) {
stringbuffer1.append(s3);
System.out.println(s3);
}
bufferedreader.close();
httpurlconnection = null;
}
}

Result:

OK
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>

Request

POST /axis/services/Version HTTP/1.1
Host: localhost
Content-Length: 253
Content-Type: text/xml; charset=UTF-8
SOAPAction: http://localhost:8080/axis/services/Version
User-Agent: Java/1.4.2
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><getVersion></getVersion></SOAP-ENV:Body></SOAP-ENV:Envelope>

Response

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 15 Jul 2008 11:41:14 GMT

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>


Using AXIS classes:

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;

public class Main {
public static void main(String[] args) throws Exception {
String endpoint = "http://localhost:8080/axis/services/Version";
Call call = (Call) new Service().createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("", "getVersion"));
String ret = (String) call.invoke(new Object[] { });
System.out.println(ret);
}
}

Result:

Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)

Request:

POST /axis/services/Version HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:8080
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 340

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersion soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></soapenv:Body></soapenv:Envelope>

Response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 15 Jul 2008 10:35:47 GMT
Connection: close

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>

Java and XML: miscellaneous notes

- Java 1.4 includes the Crimson parser, though the Axis team prefer Xerces.
- If you are installing Tomcat, get the latest 4.1.x version, and the full distribution, not the LE version for Java 1.4, as that omits the Xerces XML parser.
- SOAP messages are XML messages. Messages consist of one or more SOAP elements inside an envelope, Headers and the SOAP Body. SOAP has two syntaxes for describing the data in these elements, which is a clear descendant of the XML RPC system, and XML Schema, which is the newer system.
- Axis implements the JAX-RPC API, one of the standard ways to program Java services.
- To add an XML parser, acquire the JAXP 1.1 XML compliant parser of your choice. We recommend Xerces jars from the xml-xerces distribution, though others mostly work.
- Axis is compiled in the JAR file axis.jar; it implements the JAX-RPC API declared in the JAR files jaxrpc.jar and saaj.jar.
- The examples in this guide use Xerces. This guide adds xml-apis.jar and xercesImpl.jar to the AXISCLASSPATH so that Axis can find the parser. (from Installing and deploying web applications using xml-axis).
- Axis stands for, it's Apache EXtensible Interaction System.
- JaxMe - an implementation of JAXB, the specification for Java/XML binding.
A SOAP message is an ordinary XML document containing the following elements:
* A required Envelope element that identifies the XML document as a SOAP message
* An optional Header element that contains header information
* A required Body element that contains call and response information
* An optional Fault element that provides information about errors that occurred while processing the message
-Axis is one of the best Java-based Web services engines. It's better architected and much faster than its Apache SOAP predecessor.
-XML infoset is an abstract model of all the information in an XML document or document fragment.
- Dynamic invocation interface (DII)

-Communication Patterns
With Web Services, you can essentially distinguish three different ways of communication:

* Remote procedure call: Client sends a SOAP request to the service provider and then waits for a SOAP response (synchronous communication).
* Messaging: Client sends a SOAP request and expects no SOAP response back (one-way communication)
* Asynchronous callback: A client calls the service with one of the above methods. Later, the two parties switch roles for a callback call. This pattern can be built from either of the first two.

- WSDL 1.1 distinguishes two different binding styles (referred to as soap:binding styles): RPC and Document.

7/9/08


Java and XML: validation XML

JAXP 1.3

String schemaLang = "http://www.w3.org/2001/XMLSchema";
SchemaFactory factory = SchemaFactory.newInstance(schemaLang);
Schema schema = factory.newSchema(new StreamSource("sample.xsd"));
Validator validator = schema.newValidator();
validator.validate(new StreamSource("sample.xml"));

Java and XML: generating XML


DOM API:

import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;

public class Main {

 public static void main(String[] args) throws Exception {

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  Document xmldoc = factory.newDocumentBuilder().getDOMImplementation().createDocument(null, "PhoneBook", null);

  Element root = xmldoc.getDocumentElement();
  Element e = xmldoc.createElementNS(null, "BookRecord");
  Node n = xmldoc.createTextNode("Value");
  e.appendChild(n);
  root.appendChild(e);

  Transformer serializer = TransformerFactory.newInstance().newTransformer();
  serializer.setOutputProperty(OutputKeys.INDENT,"yes");
  serializer.transform(new DOMSource(xmldoc), new StreamResult(new PrintWriter(System.out)));
 }
}


SAX API:

import java.io.PrintWriter;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.helpers.*;

public class Main {

 public static void main(String argv[]) throws Exception {

  SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
  TransformerHandler hd = tf.newTransformerHandler();
  hd.getTransformer().setOutputProperty(OutputKeys.INDENT,"yes");
  hd.setResult(new StreamResult(new PrintWriter( System.out)));

  hd.startDocument();
  hd.startElement("", "", "PhoneBook",new AttributesImpl());
  hd.startElement("", "","BookRecord", new AttributesImpl());
  hd.characters("Value".toCharArray(), 0, 5);
  hd.endElement("", "", "BookRecord");
  hd.endElement("", "", "PhoneBook");
  hd.endDocument();
 }
}


JDOM API:

package com;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class Main {

 public static void main(String argv[]) throws Exception {

  Document doc = new Document();
  Element e = new Element("PhoneBook");
  e.addContent(new Element("BookRecord").setText("Value"));
  doc.addContent(e);

  XMLOutputter outp = new XMLOutputter();
  Format f = Format.getPrettyFormat();
  //f.setIndent(" ");
  outp.setFormat(f);
  outp.output(doc, System.out);
 }
}


As result in all cases:

<?xml version="1.0" encoding="UTF-8"?>
<PhoneBook>
<BookRecord>Value</BookRecord>
</PhoneBook>



XML Serialization with java.beans.XMLEncoder class

import java.beans.XMLEncoder;

public class Main {

 public static void main(String[] args) throws Exception {
  XMLEncoder xenc = new XMLEncoder(System.out);
  xenc.writeObject("Some String");
  xenc.flush();
  xenc.close();
 }
}

Output:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
 <string>Some String</string>
</java>

Or more interesting:

import java.beans.XMLEncoder;

public class Main {

 public static void main(String[] args) throws Exception {

  Foo[] arr = {new Foo(), new Foo()};
  XMLEncoder encoder = new XMLEncoder(System.out);
  encoder.writeObject(arr);
  encoder.close();
  }

  public static class Foo {

  private int foo = 10 ;
  public int getFoo() {
   return foo;
  }

  public void setFoo(int foo) {
   this.foo = foo;
  }
 }
}


<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
 <array class="com.Main$Foo" length="2">
  <void index="0">
   <object class="com.Main$Foo"/>
  </void>
  <void index="1">
   <object class="com.Main$Foo"/>
  </void>
 </array>
</java>

As you can see - not so optimistic. For the things to be serialized propery, you need bean pattern getter methods, and sometimes even setters: so for simple java bean serialization will work fine.


XStream - a lightweight open source Java library for serializing Java objects to XML and back again.


import com.thoughtworks.xstream.XStream;

public class Main {

 public static void main(String[] args) throws Exception {

  XStream xstream = new XStream();
  xstream.alias("Foo", Foo.class);
  String xml = xstream.toXML(new Foo());
  System.out.println(xml);
 }

 public static class Foo {

  public int fooInt = 10 ;
  public String fooStr = "20";
  }
}


<Foo>
 <fooInt>10</fooInt>
 <fooStr>20</fooStr>
</Foo>

In case of List it behave too pretty good:

 List<Foo> list = new LinkedList<Foo>();
 list.add(new Foo());
 list.add(new Foo());
 String xml = xstream.toXML(list);

Result:

<linked-list>
 <Foo>
  <fooInt>10</fooInt>
  <fooStr>20</fooStr>
 </Foo>
 <Foo>
  <fooInt>10</fooInt>
  <fooStr>20</fooStr>
 </Foo>
</linked-list>

Java and XML: query over XML

There is not included API for XQuery in Java 5 or 6. There is not included XPath API in Java till 5. But in java 5 and higher there is facilities for addressing element or group of elements via XPath. Probably in Java 7 it will be realized (XQJ or JSR 225 - like JDBC). Any case SUN is not only vendor of such kind of API.

XPath with Saxon
SAXON is the XSLT and XQuery Processor. Most XSLT and XQuery functionality in Saxon will work without installing JAXP 1.3.

import net.sf.saxon.dom.DOMNodeList;
import net.sf.saxon.om.NamespaceConstant;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.xpath.XPathEvaluator;
import org.xml.sax.InputSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.transform.sax.SAXSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.FileInputStream;
import java.util.Iterator;
import net.sf.saxon.dom.ElementOverNodeInfo;

public class XPathExample implements NamespaceContext {

 public static void main (String args[]) throws Exception {
  System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_SAXON, "net.sf.saxon.xpath.XPathFactoryImpl");
  XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);
  XPath xpe = xpf.newXPath();
  InputSource is = new InputSource(new FileInputStream("D:/dev/Temp_java/src/com/PhoneBook.xml"));
  SAXSource ss = new SAXSource(is);
  NodeInfo doc = ((XPathEvaluator)xpe).setSource(ss);
  XPathExpression findLine = xpe.compile("/*[1]/*[1]");
  DOMNodeList matchedLines = (DOMNodeList)findLine.evaluate(doc, XPathConstants.NODESET) ;
  if (matchedLines != null) {
   for (int i = 0; i < matchedLines.getLength(); i++) {
    ElementOverNodeInfo info =((ElementOverNodeInfo)matchedLines.item(i));
    System.out.println(info.getTextContent());
   }
  }
 }

 public String getNamespaceURI(String prefix) {
  return null;
 }
 public String getPrefix(String namespaceURI) {
  return null;
 }
 public Iterator getPrefixes(String namespaceURI) {
  return null;
 }
}

Result:

0
Alex
Kuiv, Kominterna 28
aillusions@gmail.com
+380664392825


XPath with JAXP 1.3
JAXP is the Java API for XML Processing. In version SE 1.5 it included by default but there is version JAXP 1.3 for JDK 1.4 (by default has JAXP 1.1). To use this API in 1.4 property -Djava.endorsed.dirs=DIR_WITH_JAXP1.3_JARS should be set, or copy all of the jar files except jaxp-api.jar into /jre/lib/endorsed.

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XPathDemo {

 public static void main(String[] args) throws Exception {

  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String xpathExpression = "/*/pb:BookRecord/pb:id";

  XPathFactory xpf = XPathFactory.newInstance();
  XPath xpath = xpf.newXPath();

  NamespaceContextImpl namespaceContextImpl = new NamespaceContextImpl();
  namespaceContextImpl.bindPrefixToNamespaceURI("pb","http://www.epam.com/com/PhoneBook");

  xpath.setNamespaceContext(namespaceContextImpl);
  FileInputStream saxStream = new FileInputStream(xmlFile);
  NodeList saxNodeList = null;
  saxNodeList = (NodeList)xpath.evaluate(xpathExpression, new InputSource(saxStream), XPathConstants.NODESET);

  for (int i = 0; i < saxNodeList.getLength(); i++) {
   System.out.println(" name: " + saxNodeList.item(i).getNodeName()+", value: " + saxNodeList.item(i).getNodeValue());
  }
 }
}

class NamespaceContextImpl implements NamespaceContext {

 private HashMap prefixToNamespaceURI = new HashMap();
 private HashMap namespaceURIToPrefix = new HashMap();

 public void bindPrefixToNamespaceURI(String prefix, String namespaceURI) {
  prefixToNamespaceURI.put(prefix, namespaceURI);
  namespaceURIToPrefix.put(namespaceURI, prefix);
 }

 public String getNamespaceURI(String prefix) {
  if (prefixToNamespaceURI.containsKey(prefix))
   return (String)prefixToNamespaceURI.get(prefix);
  return XMLConstants.NULL_NS_URI;
 }

 public String getPrefix(String namespaceURI) {
  if (namespaceURIToPrefix.containsKey(namespaceURI))
   return (String)namespaceURIToPrefix.get(namespaceURI);
  return null;
 }

 public Iterator getPrefixes(String namespaceURI) {
  throw new UnsupportedOperationException("NamespaceContextImpl#getPrefixes(String namespaceURI) not implemented");
 }
}

And result:

name: pb:id, value: null
name: pb:id, value: null
name: pb:id, value: null


XPath with Jaxen
Jaxen is able to interact with DOM, Dom4j and JDOM.

import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.jaxen.dom.DOMXPath;
import org.jaxen.XPath;
import java.util.List;
import java.util.Iterator;

public class Main {

 public static void main(String argv[]) throws Exception {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  factory.setNamespaceAware(true);

  Document doc = factory.newDocumentBuilder().parse("D:/dev/Temp_java/src/com/PhoneBook.xml");
  XPath xpath = new DOMXPath("//pb:id");
  xpath.addNamespace("pb", "http://www.epam.com/com/PhoneBook");
  xpath.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

  List results = xpath.selectNodes(doc);
  Iterator resultIter = results.iterator();

  while(resultIter.hasNext()){
   System.out.println( resultIter.next());
  }
 }
}

As result:

<pb:id>0</pb:id>
<pb:id>1</pb:id>
<pb:id>2</pb:id>


XPath with SAXPath
SAXPath has been merged into the Jaxen codebase and is no longer being maintained separately.

XPath with Xalan
Xalan-Java is an XSLT processor for transforming XML documents: http://xml.apache.org/xalan-j. Xalan includes the JAXP packages, implements the TrAX portion of that API (javax.xml.transform....), implements the XPath API of JAXP (javax.xml.xpath....), and includes xercesImpl.jar from Xerces-Java 2.9.0, which implements the parser portion of the API (javax.xml.parser....).

import java.io.FileInputStream;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;

public class ApplyXPath {

 public static void main(String[] args) throws Exception {

  String filename = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String xpath = "/*[1]/*[1]";

  InputSource in = new InputSource(new FileInputStream(filename));
  DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
  dfactory.setNamespaceAware(true);
  Document doc = dfactory.newDocumentBuilder().parse(in);
  Transformer serializer = TransformerFactory.newInstance().newTransformer();
  serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

  NodeIterator nl = XPathAPI.selectNodeIterator(doc, xpath);

  Node n;
  while ((n = nl.nextNode()) != null) {
   serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(System.out)));
  }
 }
}

Result:

<pb:BookRecord xmlns:pb="http://www.epam.com/com/PhoneBook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <pb:id>0</pb:id>
  <pb:name>Alex</pb:name>
  <pb:address>Kuiv, Kominterna 28</pb:address>
  <pb:email>aillusions@gmail.com</pb:email>
  <pb:phone>+380664392825</pb:phone>
 </pb:BookRecord>

Java and XML: transformation XML

We can process our xml with code:

import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Main {

 public static void main(String argv[]) throws Exception {
  File xmlFile = new File("src/com/PhoneBook.xml");
  File xsltFile = new File("src/com/PhoneBook.xsl");
  TransformerFactory transFact = TransformerFactory.newInstance();
  Transformer trans = transFact.newTransformer(new StreamSource(xsltFile));
  trans.transform(new StreamSource(xmlFile), new StreamResult(System.out));
 }
}

And result:

<?xml version="1.0" encoding="UTF-8"?>
<strong>Value</strong>

Java and XML: parsing XML

SAX - simple API for XML processing:

SAXParser saxParser = SAXParserFactory.newInstance().newSAXPar\ser();
saxParser.parse(new ByteArrayInputStream("<aaa>bbb</aaa>".getBytes()), new DefaultHandler());

Above is simplest sample. Now I am going to show parsing with validation by SAX.
Let's create simple SAX parser handler:

class PhoneBookHandler extends DefaultHandler{
 public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
  System.out.println(localName);
  super.startElement(uri, localName, name, attributes);
 }
 public void error(SAXParseException e) throws SAXException {
  e.printStackTrace();
  super.error(e);
 }

And main code:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;

public class Main {
 public static void main(String argv[]) throws Exception {
  SAXParserFactory pf = SAXParserFactory.newInstance();
  pf.setNamespaceAware(true);
  pf.setValidating(true);
  SAXParser p = pf.newSAXParser();
  p.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
  p.parse("D:/dev/Temp_java/src/com/PhoneBook.xml", new PhoneBookHandler());
 }
}

If you do not have schemaLocation in your xml file, you can define schema location in parser property:

p.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", new File("%PATH_TO_YOUR_XSD%/PhoneBook.xsd"));

schemaSource property in parser is more important than schemaLocation in xml instance.

DOM - document object model

import javax.xml.parsers.*;
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("D:/dev/Temp_java/src/com/xml.xml"); System.out.println(doc.getElementsByTagName("Record").item(0).getFirstChild().getNextSibling());

JDOM - java-oriented (not XML) representation of an XML document
JDOM is the Java-based solution for accessing, manipulating, and outputting XML data from Java code. It corresponds JSR-102 - API for easy and efficient reading, manipulation, and writing of XML documents and XML data.

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build("D:/dev/Temp_java/src/com/PhoneBook.xml");
System.out.println(doc.getRootElement().getChildren().get(0).toString());

StAX - Streaming API for XML
JSR 173 defines a pull streaming model, StAX (short for "Streaming API for XML"), for processing XML documents. In this model, unlike in SAX, the client can start, proceed, pause, and resume the parsing process. The client has complete control.
A StAX Implementation:
- Sun's Implementation - SJSXP
- BEA Reference Implementation
- WoodSToX XML Processor
- Oracle StAX Pull Parser Preview
- Codehaus StAX
Sun Java Streaming XML Parser - SJSXP - is an implementation of the StAX API. We need sjsxp.jar and jsr173_1.0_api.jar in class path

import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;

public class Main {

 public static void main(String argv[]) throws Exception {
  FileInputStream fileInputStream = new FileInputStream("D:/dev/Temp_java/src/com/PhoneBook.xml");
  XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);

  while (true) {
   int event = xmlStreamReader.next();
   if (event == XMLStreamConstants.END_DOCUMENT) {
    xmlStreamReader.close();
    break;
   }
   if (event == XMLStreamConstants.START_ELEMENT) {
    System.out.println(xmlStreamReader.getLocalName());
   }
  }
 }
}

Result:

PhoneBook
BookRecord
id
name
address
email
phone
BookRecord
id
name
address
email
phone
BookRecord
id
name
address
email
phone

Apache Axiom - AXis Object Model - the XML object model that uses StAX as its underlying XML parsing methodology.
XML infoset refers to the information included inside the XML, and for programmatic manipulation it is convenient to have a representation of this XML infoset in a language specific manner. For an object oriented language the obvious choice is a model made up of objects. DOM and JDOM are two such XML models. Axiom is too, but it uses "pull parsing" - a recent trend in XML processing. Axiom is based on StAX (JSR 173 ), which is the standard streaming pull parser API. Axiom needs JAXP 1.3 so java 5 should be used, or -Djava.endorsed.dirs=D:/env/xml/jaxp-1_3 should be set.

import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;

public class Main {

 public static void main(String argv[]) throws Exception {
  String xmlFName = "D:/dev/Temp_java/src/com/PhoneBook.xml";

  XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream(xmlFName));
  StAXOMBuilder builder = new StAXOMBuilder(parser);
  OMElement documentElement = builder.getDocumentElement();
  System.out.println(documentElement.getChildElements().next());
 }
}

Xerces - Apache parsers that supports standard APIs - most popular SAX and DOM parser.
Xerces is a family of software packages for parsing and manipulating XML, it provides both XML parsing and generation.
Creating a DOM Parser:

import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;

public class Main {

 public static void main(String argv[]) throws Exception {
  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  DOMParser parser = new DOMParser();
  parser.parse(xmlFile);
  Document document = parser.getDocument();
  System.out.println(document.getChildNodes().item(0).getNodeName());
 }
}

Result:

pb:PhoneBook

Creating a SAX Parser:

import org.xml.sax.AttributeList;
import org.xml.sax.DocumentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.ParserFactory;

public class Main implements DocumentHandler {

 public static void main(String argv[]) throws Exception {
  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String parserClass = "org.apache.xerces.parsers.SAXParser";
  Parser parser = ParserFactory.makeParser(parserClass);
  parser.setDocumentHandler(new Main());
  parser.parse(xmlFile);
 }

 public void characters(char[] ch, int start, int length) throws SAXException {}
 public void endDocument() throws SAXException {}
 public void endElement(String name) throws SAXException {}
 public void ignorableWhitespace(char[] ch, int start, int length){}
 public void processingInstruction(String target, String data)throws SAXException {}
 public void setDocumentLocator(Locator locator) {}
 public void startDocument() throws SAXException {}
 public void startElement(String name, AttributeList atts) throws SAXException {
  System.out.println(name);
 }
}

Result:

pb:PhoneBook
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone

Crimson XML – A faster SAX and DOM parser
...
Sparta XML – A fast and small SAX and DOM parser also includes an XPath subset
...
StelsXML is a JDBC type 4 driver that allows to perform SQL queries and other JDBC operations on XML files
...

7/2/08


Java and XML: intro

Let's consider PhoneBook.xml:

<?xml version="1.0"?>
<pb:PhoneBook xmlns:pb="http://www.epam.com/com/PhoneBook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.epam.com/com/PhoneBook PhoneBook.xsd">
 <pb:BookRecord>
  <pb:id>0</pb:id>
  <pb:name>Alex</pb:name>
  <pb:address>Kuiv, Kominterna 28</pb:address>
  <pb:email>aillusions@gmail.com</pb:email>
  <pb:phone>+380664392111</pb:phone>
 </pb:BookRecord>
 <pb:BookRecord>
  <pb:id>1</pb:id>
  <pb:name>Zhanna</pb:name>
  <pb:address>Kuiv, Showkunenko 3</pb:address>
  <pb:email>estetka@mail.ru</pb:email>
  <pb:phone>+380666464111</pb:phone>
 </pb:BookRecord>
</pb:PhoneBook>

xsd file PhoneBook.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.epam.com/com/PhoneBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <xsd:element name="PhoneBook">
  <xsd:complexType>
   <xsd:sequence minOccurs="0" maxOccurs="unbounded">
    <xsd:element name="BookRecord">
     <xsd:complexType>
      <xsd:sequence minOccurs="0">
       <xsd:element type="xsd:int" name="id" />
       <xsd:element type="xsd:string" name="name" />
       <xsd:element type="xsd:string" name="address" />
       <xsd:element type="xsd:string" name="email" />
       <xsd:element type="xsd:string" name="phone" />
      </xsd:sequence>
     </xsd:complexType>
    </xsd:element>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>

xsl file PhoneBook.xsl:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <strong>
   <xsl:text>Value</xsl:text>
  </strong>
 </xsl:template>
</xsl:stylesheet>