Monday, May 11, 2015

XML: Create XML from POJOs

XML is using to describe data. So we can use xml in many areas to store and communicate data. In here I'm showing how to build an xml structure using java application to store data in POJOs.

First I crated Java project using eclipse and create POJO class to model Student object. In my student object I have Student Id, Name, Registered Year and NIC number. With that class we can create several student objects and can transform them in to XML file.

In XML creation I used javax.xml.parsers.DocumentBuilderFactory. It is also used to build the XML document and defines a factory API that enables applications to obtain a parser that produces DOM object trees from XML documents. I'm using javax.xml.parsers.DocumentBuilder to obtain DOM Document instances from the empty XML document which I instantiated using DocumentBuilderFactory. An instance of DocumentBuilder class can be obtained from the documentBuilderFactory.newDocumentBuilder() method. Once an instance of this class is obtained, XML can be parsed from a variety of input sources. These input sources are InputStreams, Files, URLs, and SAX InputSources. But in here I'm using it only to create new XML document instead of parsing existing one.

Then I'm creating a new org.w3c.dom.Document object using documentBuilder and appending elements in to it from my POJOs.

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();

Now its time to create XML elements and append them to the created document object. First we have to create a root element and add if any XML processing instructions available before the root element. In this example I'm using xml-stylesheet to style the XML. In here I have used org.w3c.dom.Element interface to create XML elements in document. The Element interface represents an element in an HTML or XML document. Elements may have attributes associated with them; since the Element interface inherits from Node, the generic Node interface attribute attributes may be used to retrieve the set of all attributes for an element. There are methods on the Element interface to retrieve either an Attr object by name or an attribute value by name. In XML, where an attribute value may contain entity references, an Attr object should be retrieved to examine the possibly fairly complex sub-tree representing the attribute value. On the other hand, in HTML, where all attributes have simple string values, methods to directly access an attribute value can safely be used as a convenience.

// Create the root element
Element studentsElement = document.createElement("studentsns:students");
studentsElement.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:studentsns", "http://www.charitha.org/students");
studentsElement.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
studentsElement.setAttribute("xsi:schemaLocation", "StudentsSchema.xsd");
document.appendChild(studentsElement);

Then I'm appending my XML processing instructions to document before the root element.

// Create processing instructions for style sheet
Node style = document.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"students.xsl\"");
document.insertBefore(style, studentsElement);

Now its time to iterate through the Student objects list and append student details to XML.

for (Student s : students) {
   // create student element
   Element studentElement = document.createElement("studentsns:student");
   studentsElement.appendChild(studentElement);
   studentElement.setAttribute("id", String.valueOf(s.getStudentId()));
   // create name element
   Element nameElement = document.createElement("studentsns:name");
   nameElement.appendChild(document.createTextNode(s.getStudentName()));
   studentElement.appendChild(nameElement);
   // create year element
   Element yearElement = document.createElement("studentsns:student");
   yearElement.appendChild(document.createTextNode(String.valueOf(s.getRegYear())));
   studentElement.appendChild(yearElement);
   // create nic element
   Element nicElement = document.createElement("studentsns:nic");
   nicElement.appendChild(document.createTextNode(s.getNic()));
   studentElement.appendChild(nicElement);
}

Finally we have to transform DOM object of document to XML using javax.xml.transform.TransformerFactory. An instance of javax.xml.transform.Transformer class can be obtained with the transformerFactory.newTransformer method. This instance may then be used to process XML from a variety of sources and write the transformation output to a variety of sinks.

We have to create javax.xml.transform.dom.DOMSource as a holder for a transformation Source tree in the form of a Document Object Model (DOM) tree. And also we need javax.xml.transform.stream.StreamResult to stream XML in to file. Then we can finally create XML file output by using DOMSource and StreamResult.

// transform DOM object to xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File("student.xml"));
transformer.transform(domSource, streamResult);

Generated XML file will be available in project folder.

Click here to download sample eclipse project.

No comments:

Post a Comment