(Tutorial) Java and XML - Tutorial
Java and XML - Tutorial:
[ XML Introduction ]
1.1. XML Overview
XML stands for Extensible Markup Language and was defined 1998 by the World Wide Web Consortium (W3C).
A XML document consists out of elements, each element has a start tag, content and an end tag. A XML document must have exactly one root element, e.g. one tag which encloses the remaining tags. XML makes a difference between capital and non-capital letters.
A XML file is required to be well-formated.
Well-formated XML must apply to the following conditions:
-
A XML document always starts with a prolog (see below for an explanation of what a prolog is)
-
Every tag has a closing tag.
-
All tags are completely nested.
In general the following is considered as advantages in using XML for data processing / representation.
-
XML is Plain text
-
XML allows the data identification without any display information
-
Style can be defined via XSL
-
Easily processed due to it regular and consistent notation
-
XML files are hierarchical
The following is a valid, well-formated XML file.
<?xml version="1.0"?> <!-- This is a comment -> <adress> <name>Lars </name> <street> Test </street> <telephon number= "0123"/> </address>
A XML document always starts with a prolog which describes XML file. This prolog can be minimal, e.g. <?xml version="1.0"?> or can contain other information, e.g. the encoding, e.g. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
A tag which doesn't enclose any content is know as an "empty tag". For example: <flag/>
Java contains several methods to access XML.
W3C Standard for programming API for general programming languages. Access is done over an object tree.
Sequential reading of XML files. Can not be used to create XML documents.
SAX provides an Event-Driven XML Processing following the Push-Parsing Model. What this model means is that in SAX, Applications will register Listeners in the form of Handlers to the Parser and will get notified through Call-back methods. Here the SAX Parser takes the control over Application thread by Pushing Events to the Application.
Streaming API for XML, simply called StaX, is an API for reading and writing XML Documents.
StaX is a Pull-Parsing model. Application can take the control over parsing the XML documents by pulling (taking) the events from the parser.
The core StaX API falls into two categories and they are listed below. They are
-
Cursor API
-
Event Iterator API
Applications can any of these two API for parsing XML documents. The following will focus on the event iterator API as I consider it more convenient to use.
The event iterator API has two main interfaces: XMLEventReader for parsing XML and XMLEventWriter for generating XML.
Applications loop over the entire document requesting for the Next Event. The Event Iterator API is implemented on top of Cursor API.
Lets assume you would like to read the following simple XML file.
<?xml version="1.0" encoding="UTF-8"?> <config> <mode>1</mode> <unit>900</unit> <current>1</current> <interactive>1</interactive> </config>
The following reads the xml file and puts the content of the example XML file to the the standard output.
package brain.xml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
public class ConfigFileStaX2 {
private String configFile;
public void setFile(String configFile) {
this.configFile = configFile;
}
public void readConfig() {
try {
// First create a new XMLInputFactory
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
// Setup a new eventReader
InputStream in = new FileInputStream(configFile);
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
// Read the XML document
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
if (event.asStartElement().getName().getLocalPart() == ("mode")) {
event = eventReader.nextEvent();
System.out.println(event.asCharacters().getData());
continue;
}
if (event.asStartElement().getName().getLocalPart() == ("unit")) {
event = eventReader.nextEvent();
System.out.println(event.asCharacters().getData());
continue;
}
if (event.asStartElement().getName().getLocalPart() == ("current")) {
event = eventReader.nextEvent();
System.out.println(event.asCharacters().getData());
continue;
}
if (event.asStartElement().getName().getLocalPart() == ("interactive")) {
event = eventReader.nextEvent();
System.out.println(event.asCharacters().getData());
continue;
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
ConfigFileStaX2 read = new ConfigFileStaX2();
read.setFile("config.xml");
read.readConfig();
}
}
Lets assume you would like to write the following simple XML file.
<?xml version="1.0" encoding="UTF-8"?> <config> <mode>1</mode> <unit>900</unit> <current>1</current> <interactive>1</interactive> </config>
StaX does not provide functionality to format the XML file automatically. So you have to add end-of-lines and tab information to your XML file.
package brain.xml;
import java.io.FileOutputStream;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
public class WriteConfigFile {
private String configFile;
public void setFile(String configFile) {
this.configFile = configFile;
}
public void saveConfig() throws Exception {
// Create a XMLOutputFactory
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
// Create XMLEventWriter
XMLEventWriter eventWriter = outputFactory
.createXMLEventWriter(new FileOutputStream(configFile));
// Create a EventFactory
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
// Create and write Start Tag
StartDocument startDocument = eventFactory.createStartDocument();
eventWriter.add(startDocument);
// Create config open tag
StartElement configStartElement = eventFactory.createStartElement("",
"", "config");
eventWriter.add(configStartElement);
eventWriter.add(end);
// Write the different nodes
createNode(eventWriter, "mode", "1");
createNode(eventWriter, "unit", "901");
createNode(eventWriter, "current", "0");
createNode(eventWriter, "interactive", "0");
eventWriter.add(eventFactory.createEndElement("", "", "config"));
eventWriter.add(end);
eventWriter.add(eventFactory.createEndDocument());
eventWriter.close();
}
private void createNode(XMLEventWriter eventWriter, String name,
String value) throws XMLStreamException {
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
XMLEvent tab = eventFactory.createDTD("\t");
// Create Start node
StartElement sElement = eventFactory.createStartElement("", "", name);
eventWriter.add(tab);
eventWriter.add(sElement);
// Create Content
Characters characters = eventFactory.createCharacters(value);
eventWriter.add(characters);
// Create End node
EndElement eElement = eventFactory.createEndElement("", "", name);
eventWriter.add(eElement);
eventWriter.add(end);
}
/**
* @param args
*/
public static void main(String[] args) {
WriteConfigFile configFile = new WriteConfigFile();
configFile.setFile("config2.xml");
try {
configFile.saveConfig();
} catch (Exception e) {
e.printStackTrace();
}
}
}
XPath (XML Path Language) is a language for selecting / searching nodes from an XML document. Java 5 introduced the javax.xml.xpath package which provides a XPath library.
The following explains how to use XPath to query an XML document via Java.
The following explains how to use XPath. Create a new Java project called "UsingXPath".
Create the following xml file.
<?xml version="1.0" encoding="UTF-8"?> <people> <person> <firstname>Lars</firstname> <lastname>Vogel</lastname> <city>Heidelberg</city> </person> <person> <firstname>Jim</firstname> <lastname>Knopf</lastname> <city>Heidelberg</city> </person> <person> <firstname>Lars</firstname> <lastname>Strangelastname</lastname> <city>London</city> </person> <person> <firstname>Landerman</firstname> <lastname>Petrelli</lastname> <city>Somewhere</city> </person> <person> <firstname>Lars</firstname> <lastname>Tim</lastname> <city>SomewhereElse</city> </person> </people>
Create a new package "myxml" and a new Java class "QueryXML".
package myxml;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class QueryXML {
public void query() throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
// Standard of reading a XML file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
XPathExpression expr = null;
builder = factory.newDocumentBuilder();
doc = builder.parse("person.xml");
// Create a XPathFactory
XPathFactory xFactory = XPathFactory.newInstance();
// Create a XPath object
XPath xpath = xFactory.newXPath();
// Compile the XPath expression
expr = xpath.compile("//person[firstname='Lars']/lastname/text()");
// Run the query and get a nodeset
Object result = expr.evaluate(doc, XPathConstants.NODESET);
// Cast the result to a DOM NodeList
NodeList nodes = (NodeList) result;
for (int i=0; i<nodes.getLength();i++){
System.out.println(nodes.item(i).getNodeValue());
}
// New XPath expression to get the number of people with name lars
expr = xpath.compile("count(//person[firstname='Lars'])");
// Run the query and get the number of nodes
Double number = (Double) expr.evaluate(doc, XPathConstants.NUMBER);
System.out.println("Number of objects " +number);
// Do we have more then 2 people with name lars?
expr = xpath.compile("count(//person[firstname='Lars']) >2");
// Run the query and get the number of nodes
Boolean check = (Boolean) expr.evaluate(doc, XPathConstants.BOOLEAN);
System.out.println(check);
}
public static void main(String[] args) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException {
QueryXML process = new QueryXML();
process.query();
}
}
5. Links and Literature
http://www.xml.com/pub/a/2003/09/17/stax.html Nice introduction into Stax
http://www.javabeat.net/javabeat/java6/articles/2007/06/java-6-0-new-features-part-2/2 Introduction to the Streaming API for XML
http://www.ibm.com/developerworks/library/x-javaxpathapi.html The Java XPath API (by Elliotte Rusty Harold)
Courtesy : vogella.de
- guru's blog
- Login to post comments
