import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.InputSource; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import java.io.IOException; import javax.swing.JTree; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class DOMCompact{ public static void main(String argv[]) { // is there anything to do? if (argv.length != 1) { System.out.println("Usage: java DOMCompact file"); System.exit(1); } // parse file try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); factory.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new CompactErrorHandler()); Document doc = builder.parse(argv[0]); Node docElem=doc.getDocumentElement(); stripSpace(docElem); compact(docElem,""); System.out.println(); new TreeViewer( new JTree(new DefaultTreeModel( TreeViewer.jTreeBuild(docElem)))).setVisible(true); } catch (SAXParseException e) { System.out.println(argv[0]+"is not well-formed"); System.out.println(e.getMessage()+"at line "+e.getLineNumber()+ ", column "+e.getColumnNumber()); } catch (SAXException e){ System.out.println(e.getMessage()); } catch (ParserConfigurationException e){ System.out.println("Parser configuration error"); } catch (IOException e) { System.out.println("IO Error on "+argv[0]); } } // remove empty text nodes (ie nothing else than spaces and carriage return) // and nodes that are not text or element ones private static void stripSpace(Node node){ Node child = node.getFirstChild(); while(child!=null){ // save the sibling of the node that will // perhaps be removed and set to null Node c = child.getNextSibling(); if((child.getNodeType()==Node.TEXT_NODE && child.getNodeValue().trim().length()==0) || ((child.getNodeType()!=Node.TEXT_NODE)&& (child.getNodeType()!=Node.ELEMENT_NODE))) node.removeChild(child); else // process children recursively stripSpace(child); child=c; } } public static void compact(Node node,String indent) { if (node == null)return; switch (node.getNodeType()) { case Node.ELEMENT_NODE: { System.out.print(node.getNodeName()+'['); indent += blanks(node.getNodeName().length()+1); NamedNodeMap attrs = node.getAttributes(); boolean first=true; for (int i = 0; i < attrs.getLength(); i++) { if(!first)System.out.print('\n'+indent); System.out.print('@'+attrs.item(i).getNodeName()+'[' +attrs.item(i).getNodeValue()+']'); first=false; } for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()){ if(!first) System.out.print('\n'+indent); compact(child,indent); first=false; } System.out.print(']'); break; } case Node.TEXT_NODE: { System.out.print(node.getNodeValue().trim()); break; } } } // production of string of spaces with a lazy StringBuffer private static StringBuffer blanks = new StringBuffer(); private static String blanks(int n){ for(int i=blanks.length();i