XML Java

/**
 * Copyright (c) 2006-2010 Richard Rodgers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//package com.monad.homerun.util;
import java.io.IOException;
import java.io.Writer;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
 * DocWriter has a static method for writing XML documents with a writer
 */
public class DocWriter
{
  // indentation constant: 2 spaces
    private static final String SINGLE_INDENT = " ";
    
    public static void writeNodeToStream(Node node, Writer out) throws IOException {
    serializeNode(node, out, "");
    out.write('\n');
    out.flush();
    }
    
    /**
     * Writes a document to a stream
     * 
     * @param doc
     *        the XML docuument to write
     * @param out
     *        the output stream to write to
     * @throws IOException
     */
    public static void writeDocToStream( Document doc, Writer out )
                                         throws IOException
  {
    serializeNode( doc, out, "" );
    out.write( '\n' );
    out.flush();
  }
    
    private static void serializeNode( Node node, Writer out, String indent ) throws IOException
    {
      switch ( node.getNodeType() )
    {
        case Node.DOCUMENT_NODE:
          out.write( "" + '\n' );
          writeNode( ((Document)node).getDocumentElement(), out, indent );
          break;
        case Node.ELEMENT_NODE:
          writeNode( node, out, indent );
          break;
        case Node.TEXT_NODE:
          out.write( node.getNodeValue() );
          break;
        case Node.COMMENT_NODE:
          out.write( /*indent + */ "" );
          break;
        default:
          System.out.println( "Got node: " + node.getNodeName() );
          break;
    }
    }
         
    private static void writeNode( Node node, Writer out, String indent )
                                   throws IOException
    {
      out.write( nodeWithAttrs( node, indent ) );
      NodeList kids = node.getChildNodes();
      if ( kids != null )
      {
        if ( ( kids.item( 0 ) != null ) &&
           ( kids.item( 0 ).getNodeType() == Node.ELEMENT_NODE ) )
        {
          out.write( '\n' );
        }
        for ( int i = 0; i < kids.getLength(); i++ )
        {
          serializeNode( kids.item( i ), out, indent + SINGLE_INDENT );
        }
        /* RLR - bug in indent logic - seems to work OK without
           if ( ( kids.item( 0 ) != null ) &&
              ( kids.item( kids.getLength()-1).getNodeType() == Node.ELEMENT_NODE ) )
           {
             out.write( indent );
           }
           */
      }
      if ( node.hasChildNodes() )
      {
        /* indent bug - leave out
        if ( kids.item( 0 ) != null && kids.item( 0 ).getNodeType() == Node.ELEMENT_NODE )
        {
          out.write( indent );
        }
        */
        out.write( "" );
      }
    }
    
    private static String nodeWithAttrs( Node node, String indent )
    {
        StringBuffer sb = new StringBuffer();
        // indent bug - leave out
        //sb.append( indent );
        sb.append( "<" );
        sb.append( node.getNodeName() );
        NamedNodeMap attrs = node.getAttributes();
        for ( int i = 0; i < attrs.getLength(); i++ )
        {
            sb.append( " " );
            Node attrNode = attrs.item( i );
            sb.append( attrNode.getNodeName() );
            sb.append( "=\"" );
            sb.append( attrNode.getNodeValue() );
            sb.append( "\"" );
        }
        if ( ! node.hasChildNodes() )
        {
            sb.append( "/>" );
        }
        else
        {
            sb.append( ">" );
        }
        return sb.toString();
    }
}