DOM, SAX and Events

James Tauber jtauber at jtauber.com
Thu Jun 3 14:20:20 BST 1999


> So, I'm going to move to a DOM representation and do a tree-walk
> instead. I can then revisit subtrees whenever required.
> This should be no problem to implement, but leads me to wonder
> whether other people have met this same problem, and if
> so whether it'd be useful to have an event driven interface to
> the DOM?

I recently adopted this strategry for FOP (http://www.jtauber.com/fop/) so
that it can take a formatting object tree as a DOM Document as well as an
XML document. Rather stupidly, the SAX DocumentHandler, FOTreeBuilder, then
goes an builds a tree again, but this was the quickest way to get DOM
support (which people were asking for).

(As an aside: because XT allows you to specify a SAX DocumentHandler to do
output, it will be easy for me to attached XT and FOP together---stay tuned
for version 0.6.3)

JamesT

Here's my code (largely pinched from John Cowan, whose version of this is
more comprehensive :-)

package com.jtauber.fop.apps;

// FOP
import com.jtauber.fop.fo.FOTreeBuilder;

// DOM
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;

// SAX
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributeListImpl;

// Java
import java.io.PrintWriter;

/**
 * A FOProcessor that takes a DOM Document, walks the tree, firing events as
if a SAX parser
 *
 * Instantiate this class with a DOM Document and then run the format method
with a PrintWriter the PDF is to be given to
 *
 * based on John Cowan's work
 */
public class DOMProcessor extends FOProcessor
{
 private Document document; // the DOM document
/**
 * create a DOM-driven FOProcessor with the given DOM Document
 */
public DOMProcessor(Document document) {
 super(); // set up the FOProcessor
 this.document = document;
}
/**
 * Format the document to PDF on the given PrintWriter
 *
 * Most of the ideas in this method come from John Cowan
 */
public void format(PrintWriter writer) throws FOPException {
 Node currentNode;
 AttributeListImpl currentAtts;

 char[] array = null; // temporary array for making Strings into character
arrays
 currentAtts = new AttributeListImpl();

 currentNode = this.document; // start at the document element

 try {
  while (currentNode != null) {
   switch (currentNode.getNodeType()) {
    case Node.DOCUMENT_NODE:
           this.treeBuilder.startDocument();
     break;
    case Node.CDATA_SECTION_NODE:
    case Node.TEXT_NODE:
     String data = currentNode.getNodeValue();
     int datalen = data.length();
     if (array == null || array.length < datalen) // if the array isn't big
enough
      array = new char[datalen];               // make a new one
     data.getChars(0, datalen, array, 0);
     this.treeBuilder.characters(array, 0, datalen);
     break;
    case Node.PROCESSING_INSTRUCTION_NODE:

this.treeBuilder.processingInstruction(currentNode.getNodeName(),currentNode
.getNodeValue());
     break;
    case Node.ELEMENT_NODE:
     NamedNodeMap map = currentNode.getAttributes();
     currentAtts.clear();
     for (int i = map.getLength() - 1; i >= 0; i--) {
      Attr att = (Attr)(map.item(i));
      currentAtts.addAttribute(att.getName(), "CDATA", att.getValue());
     }
     this.treeBuilder.startElement(currentNode.getNodeName(), currentAtts);
     break;
   }

   Node nextNode = currentNode.getFirstChild();
   if (nextNode != null) {
    currentNode = nextNode;
    continue;
   }

   while (currentNode != null) {
    switch (currentNode.getNodeType()) {
     case Node.DOCUMENT_NODE:
      this.treeBuilder.endDocument();
      break;
     case Node.ELEMENT_NODE:
      this.treeBuilder.endElement(currentNode.getNodeName());
      break;
    }

    nextNode = currentNode.getNextSibling();
    if (nextNode != null) {
     currentNode = nextNode;
     break;
    }

    currentNode = currentNode.getParentNode();
   }
  }
 } catch (SAXException e) {
  throw new FOPException(e.getMessage());
 }
 layoutput(writer);
}
}


xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev at ic.ac.uk
Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/ and on CD-ROM/ISBN 981-02-3594-1
To (un)subscribe, mailto:majordomo at ic.ac.uk the following message;
(un)subscribe xml-dev
To subscribe to the digests, mailto:majordomo at ic.ac.uk the following message;
subscribe xml-dev-digest
List coordinator, Henry Rzepa (mailto:rzepa at ic.ac.uk)





More information about the Xml-dev mailing list