Background
In last post we say how we can efficiently parse an XML file using DocumentBuilder -
But as we had concluded that post saying we cannot parse an XML file with multiple root elements. Hence in this post we will see how we can achieve that.
To The Code....
Let say now our data.xml file looks like the following -
<data key="name" value="John"></data> <data key="age" value="23"></data> <data key="sex" value="male"></data>
That is no root element (or rather 3 root elements). If we run the previous code here we will get following Exception -
[Fatal Error] data.xml:2:2: The markup in the document following the root element must be well-formed. Exception in thread "main" org.xml.sax.SAXParseException; systemId: file:/C:/Users/athakur/newJavaWorkspace/XMLParserDemo/data.xml; lineNumber: 2; columnNumber: 2; The markup in the document following the root element must be well-formed. at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) at XMLParser.main(XMLParser.java:24)
Now lets see how can we tackle this. In this case we will take help of java.io.SequenceInputStream.
import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * * @author athakur * */ public class XMLParser { public static void main(String args[]) throws IOException, ParserConfigurationException, SAXException { File file = new File("data.xml"); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Enumeration<InputStream> streams = Collections.enumeration( Arrays.asList(new InputStream[] { new ByteArrayInputStream("<ROOT>".getBytes()), new FileInputStream(file), new ByteArrayInputStream("</ROOT>".getBytes()), })); SequenceInputStream sequenceStream = new SequenceInputStream(streams); Document doc = db.parse(sequenceStream); NodeList nodes = doc.getElementsByTagName("data"); for ( int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); String key = element.getAttribute("key"); String value = element.getAttribute("value"); System.out.println("Key : " + key + " || Value : " + value); } } }
and life is good again! Output is -
Key : name || Value : John Key : age || Value : 23 Key : sex || Value : male