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