I had to pass the XML document provided by a piece of software to an other piece of software. The first one provides the document as SAX events. But the second one expects a DOM Document. So here is a SAX-events-to-DOM-Document translator:
public class SaxToDom { public SaxToDom(XMLReader reader, InputSource input) { myReader = reader; myInput = input; } public Document makeDom() { Document doc = null; try { // Find the implementation DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); DOMImplementation impl = builder.getDOMImplementation(); // Create the document doc = impl.createDocument(null, null, null); // The Handlers and the actual building SaxToDomHandler handlers = new SaxToDomHandler(doc); myReader.setContentHandler(handlers); myReader.setErrorHandler(handlers); myReader.parse(myInput); } // For the catch handlers below, use your usual logging facilities. catch (DOMException e) { System.err.println(e); } catch (ParserConfigurationException e) { System.err.println(e); } catch (SAXException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } return doc; } private XMLReader myReader; private InputSource myInput; } class SaxToDomHandler extends DefaultHandler { public SaxToDomHandler(Document doc) { myDoc = doc; myCurrentNode = myDoc; } // Add it in the DOM tree, at the right place. public void startElement(String uri, String name, String qName, Attributes attrs) { // Create the element. Element elem = myDoc.createElementNS(uri, qName); // Add each attribute. for ( int i = 0; i < attrs.getLength(); ++i ) { String ns_uri = attrs.getURI(i); String qname = attrs.getQName(i); String value = attrs.getValue(i); Attr attr = myDoc.createAttributeNS(ns_uri, qname); attr.setValue(value); elem.setAttributeNodeNS(attr); } // Actually add it in the tree, and adjust the right place. myCurrentNode.appendChild(elem); myCurrentNode = elem; } // Adjust the current place for subsequent additions. public void endElement(String uri, String name, String qName) { myCurrentNode = myCurrentNode.getParentNode(); } // Add a new text node in the DOM tree, at the right place. public void characters(char[] ch, int start, int length) { String str = new String(ch, start, length); Text text = myDoc.createTextNode(str); myCurrentNode.appendChild(text); } // Add a new text node in the DOM tree, at the right place. public void ignorableWhitespace(char[] ch, int start, int length) { String str = new String(ch, start, length); Text text = myDoc.createTextNode(str); myCurrentNode.appendChild(text); } // Add a new text PI in the DOM tree, at the right place. public void processingInstruction(String target, String data) { ProcessingInstruction pi = myDoc.createProcessingInstruction(target, data); myCurrentNode.appendChild(pi); } // For the handlers below, use your usual logging facilities. public void error(SAXParseException e) { System.err.println("Erreur non fatale (ligne " + e.getLineNumber() + ", col " + e.getColumnNumber() + ") : " + e.getMessage()); } public void fatalError(SAXParseException e) { System.err.println("Erreur fatale : " + e.getMessage()); } public void warning(SAXParseException e) { System.err.println("Warning : " + e.getMessage()); } private Document myDoc; private Node myCurrentNode; }
Posted by Florent Georges, on 2006-08-24T15:43:00, tags: dom and sax.