(Anterior) DOM, SAX y JDOM

Procesar XML con DOM

El siguiente ejemplo al igual que el anterior de SAX esta basado en el parser Xerces 2.0, sin embargo, también se hace uso de las librerías JAXP por lo que puede ser ejecutado en otro parser Java sin complicaciones.

Dentro de este programa se define una función llamada imprimirnodos, esta función actúa de una forma recursiva, esto significa que dentro de la misma función vuelve a ser llamada, lo anterior va en acorde con el comportamiento de árbol en DOM.

Clase ArbolDOM

package com.osmosislatina.xml.dom;

// Librerías de I/O 
import java.io.*;

// Librerías de DOM 
import org.w3c.dom.*;

// Clases JAXP 
import javax.xml.parsers.DocumentBuilderFactory;  
import javax.xml.parsers.DocumentBuilder;  
import javax.xml.parsers.ParserConfigurationException;

// Clases SAX 
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class ArbolDOM  {

  //
  // Programa Principal 
  //

  // Variables 
  static Document document; 
  protected static PrintWriter out;

  /**  Inicio Programa Principal  */
  public static void main (String args [])
  {
    // Revisar que exista un archivo de entrada 
    if (args.length != 1) {
        System.err.println ("Debe indicar un archivo 
                              XML para ser procesado");
        System.exit (1);
    }

    // Crear la fabrica utilizada para DOM

    DocumentBuilderFactory factory =
      DocumentBuilderFactory.newInstance();

    try {
      // Generar el Stream para enviar a Pantalla
      out = new PrintWriter (System.out);

      // Procesar archivo 
      DocumentBuilder builder = factory.newDocumentBuilder();

      // Definir un ErrorHandler (Estilo SAX) para atrapar Errores.
      builder.setErrorHandler(

        // Definir Clase Interna para Control de Errores 
        new org.xml.sax.ErrorHandler() {

          // Ignorar Errores Fatales
          public void fatalError(SAXParseException exception)
              throws SAXException {
        }

        // Tratar errores de Validacion
        public void error(SAXParseException e) throws SAXParseException
        {
         throw e;
        }

        // Tratar avisos a Consola
        public void warning(SAXParseException err) throws SAXParseException
        {
           System.out.println("** Warning"
           + ", line " + err.getLineNumber()
           + ", uri " + err.getSystemId());
           System.out.println("   " + err.getMessage());
        }
      }
    ); 

    // Iniciar Proceso de "Parse"
    document = builder.parse( new File(args[0]) );

    ArbolDOM writer = new ArbolDOM(); 
    writer.imprimirNodos(document);

    } catch (ParserConfigurationException pexc) { 
	  pexc.printStackTrace();
    } catch (Exception exc) {
        System.out.println("   " + exc.getMessage() );

    }
}

A continuación se describe el método de impresión y un método auxiliar utilizado para ordenar los atributos de cada elemento.



public void imprimirNodos(Node node) {

    // Si ya no existen nodos por Imprimir salir.....
    if ( node == null ) {
        return;
    }

    /** Investigar el Tipo de Nodo */

    int type = node.getNodeType();
 
    /** En base al Tipo de Nodo ejecutar */
    switch ( type ) {

      // Imprimir Documento 
      case Node.DOCUMENT_NODE: {
         NodeList children = node.getChildNodes();
         for ( int iChild = 0; iChild < children.getLength(); iChild++ ) {
               imprimirNodos(children.item(iChild));
         }
         out.flush();
         break;
      }

      // Imprimir elementos con atributos
      case Node.ELEMENT_NODE: {
       out.print('<');
       out.print(node.getNodeName());
       Attr attrs[] = sortAttributes(node.getAttributes());
       for ( int i = 0; i < attrs.length; i++ ) {
          Attr attr = attrs[i];
          out.print(' ');
          out.print(attr.getNodeName());
          out.print("=\"");
          out.print(attr.getNodeValue());
          out.print('"');
       }
       out.print('>');
       NodeList children = node.getChildNodes();
       if ( children != null ) {
          int len = children.getLength();
          for ( int i = 0; i < len; i++ ) {
             imprimirNodos(children.item(i));
          }
       }
       break;
      }

      // Imprimir Texto 
      case Node.TEXT_NODE: {
	out.print(node.getNodeValue());
	break;
      }

      // Imprimir Nodos con Instrucciones de Proceso 
      case Node.PROCESSING_INSTRUCTION_NODE: {
          out.print("<?");
          out.print(node.getNodeName());
          String data = node.getNodeValue();
          if ( data != null && data.length() > 0 ) {
               out.print(' ');
               out.print(data);
          }
          out.println("?>");
          break;
      }

      // Imprimir Texto de Elementos CDATA
      case Node.CDATA_SECTION_NODE: {
	  out.print(node.getNodeValue());
	  break;  
      }

     } // Termina Switch

     // En caso de ser nodo de Elemento cerrar Tag en Pantalla 
     if ( type == Node.ELEMENT_NODE ) {
        out.print("</");
        out.print(node.getNodeName());
        out.print('>');
     }

	// Enviar a Pantalla Buffer
        out.flush();

    } // Termina Impresion de Nodos 
    
   /** Funcion utilizada para Ordenar Atributos de Elementos */

    protected Attr[] sortAttributes(NamedNodeMap attrs) {

        int len = (attrs != null) ? attrs.getLength() : 0;
        Attr array[] = new Attr[len];
        for ( int i = 0; i < len; i++ ) {
            array[i] = (Attr)attrs.item(i);
        }
        for ( int i = 0; i < len - 1; i++ ) {
            String name  = array[i].getNodeName();
            int    index = i;
            for ( int j = i + 1; j < len; j++ ) {
                String curName = array[j].getNodeName();
                if ( curName.compareTo(name) < 0 ) {
                    name  = curName;
                    index = j;
                }
            }
            if ( index != i ) {
                Attr temp    = array[i];
                array[i]     = array[index];
                array[index] = temp;
            }
        }

        return(array);

    } // Terminar ordenar de Atributos 

}

Menú Curso

XML y sus Orígenes

Manipulación y Proceso de XML

DOM, SAX y JDOM

Namespaces, Schemas y DTD's

XSL: XSLT, XPath y TraX

XMLRPC y SOAP (Web Services)

Diseño con XMLRPC

Diseño con SOAP .

Apéndice "A" (Procesando XML con parsers).

Apéndice "B" (Validando XML con Schemas y DTD's).

Apéndice "C" (XSL: XPath y "XSL Stylesheets").

Apéndice "D" (XMLRPC: Diseño).

Apéndice "E" (SOAP, WSDL, UDDI y WSIL : Diseño).