// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.util; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * @author Andrew Elmhorst * @version 2.1 * */ public class XMLStreamDocumentBuilder { /** * Creates a DOM Document from the specified XMLStreamReader * @param reader The XMLStreamReader to read from * @param namespaceAware True if the XMLStreamReader is resolving namespaces * @param rootElementName (Optional) The name of the root Document element to create. If null, the XMLStreamReader * is expected to be positioned on a document element. * @return The DOM document that has been parsed using the XMLStreamReader * @throws XMLStreamException */ public static Document build(XMLStreamReader reader, boolean namespaceAware, boolean ignoreWhitespace, String rootElementName ) throws XMLStreamException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); Document dom = null; try { dom = dbf.newDocumentBuilder().newDocument(); } catch (ParserConfigurationException pce ){ // rethrow throw new RuntimeException( "Error loading DocumentBuilderFactory: " + pce.getMessage(), pce ); } Node rootElement = dom; if( rootElementName != null ){ rootElement = dom.createElement( rootElementName ); dom.appendChild( rootElement ); } Node currentElement = rootElement; while( reader.hasNext() ){ int nodeType = reader.next(); Node parsedChild = null; switch (nodeType) { case XMLStreamConstants.SPACE: case XMLStreamConstants.ENTITY_DECLARATION: case XMLStreamConstants.NOTATION_DECLARATION: case XMLStreamConstants.START_DOCUMENT: case XMLStreamConstants.DTD: continue; case XMLStreamConstants.ENTITY_REFERENCE: parsedChild = dom.createEntityReference( reader.getLocalName()); break; case XMLStreamConstants.PROCESSING_INSTRUCTION: parsedChild = dom.createProcessingInstruction( reader.getPITarget(), reader.getPIData()); break; case XMLStreamConstants.START_ELEMENT: { String name = reader.getLocalName(); Element newElem; if ( namespaceAware ) { newElem = dom.createElementNS(reader.getNamespaceURI(), name); } else { newElem = dom.createElement( name ); } // Add attributes.... for (int i = 0, len = reader.getAttributeCount(); i < len; ++i) { String attrName = reader.getAttributeLocalName(i); if (namespaceAware) { Attr attr = dom.createAttributeNS(reader.getAttributeNamespace(i), attrName); attr.setValue(reader.getAttributeValue(i)); newElem.setAttributeNodeNS(attr); } else { Attr attr = dom.createAttribute(attrName); attr.setValue( reader.getAttributeValue(i)); newElem.setAttributeNode(attr); } } // And then 'push' new element... currentElement.appendChild(newElem); currentElement = newElem; } break; case XMLStreamConstants.CHARACTERS: if( ignoreWhitespace && reader.isWhiteSpace() ){ break; } parsedChild = dom.createTextNode(reader.getText()); break; case XMLStreamConstants.COMMENT: parsedChild = dom.createComment(reader.getText()); break; case XMLStreamConstants.CDATA: parsedChild = dom.createCDATASection( reader.getText()); break; case XMLStreamConstants.END_DOCUMENT: break; case XMLStreamConstants.END_ELEMENT: currentElement = currentElement.getParentNode(); if (currentElement == null) { currentElement = rootElement; } continue; default: throw new XMLStreamException( "Unable to process event type: " + reader.getEventType() ); } if (parsedChild != null) { currentElement.appendChild(parsedChild); } } return dom; } }