SAX writer
Vance Christiaanse
vance at textwise.com
Tue Jul 27 20:35:39 BST 1999
Mark Cheek wrote in part:
> ... I now need to serialize my new Document object to
> disk as an xml file. I cannot find any DOM classes or methods to do
> this.. can anyone help? I do not want to use IBM's or Sun's DOMWriter
> classes as we are not sure yet which parser library we are going to
> implement.
Paragraph 1.1 of the Level 1 DOM spec actually states that its scope
does not include persistent storage of a Document. I needed to do what
you want to do and I just took the code from within DOMWriter.java. The
main change I made was passing "canonical" as a parameter instead of
letting it be a global variable. This code should work with any
DOM-compliant classes, not just XML4J.
Vance
Vance Christiaanse
TextWise, LLC
vance at textwise.com
/*************************************************************
* Prints the specified node, recursively.
*
* This code was adapted from the sample code "DOMWriter.java"
* included with XML4J.
************************************************************/
public static void print(PrintWriter out, boolean canonical, Node
node) {
//-------------------------
// Is there anything to do?
//-------------------------
if (node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
//----------------
// Print document.
//----------------
case Node.DOCUMENT_NODE: {
if (!canonical) {
out.println("<?xml version=\"1.0\"
encoding=\"UTF-8\"?>");
}
print(out, canonical,
((Document)node).getDocumentElement());
out.println();
out.flush();
break;
}
//-------------------------------
// Print element with attributes.
//-------------------------------
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(normalize(attr.getNodeValue(), canonical));
out.print('"');
}
out.print('>');
NodeList children = node.getChildNodes();
if (children != null) {
int len = children.getLength();
for (int i = 0; i < len; i++) {
print(out, canonical, children.item(i));
}
}
break;
}
//-------------------------------
// Handle entity reference nodes.
//-------------------------------
case Node.ENTITY_REFERENCE_NODE: {
if (canonical) {
NodeList children = node.getChildNodes();
if (children != null) {
int len = children.getLength();
for (int i = 0; i < len; i++) {
print(out, canonical, children.item(i));
}
}
}
else {
out.print('&');
out.print(node.getNodeName());
out.print(';');
}
break;
}
//------------
// Print text.
//------------
case Node.TEXT_NODE: {
out.print(normalize(node.getNodeValue(), canonical));
break;
}
//-------------
// Print CDATA.
//-------------
case Node.CDATA_SECTION_NODE: {
if (canonical) {
out.print(normalize(node.getNodeValue(), canonical));
} else {
out.print("<![CDATA[");
out.print(node.getNodeValue());
out.print("]]>");
}
break;
}
//------------------------------
// Print processing instruction.
//------------------------------
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.print("?>");
break;
}
}
//----------------------------
// Print end tag if necessary.
//----------------------------
if (type == Node.ELEMENT_NODE) {
out.print("</");
out.print(node.getNodeName());
out.print('>');
}
}
//============================================================
// Private method to Normalize the given string.
//
// This code was adapted from the sample code "DOMWriter.java"
// included with XML4J.
//============================================================
private static String normalize(String s, boolean canonical) {
StringBuffer str = new StringBuffer();
int len = (s != null) ? s.length() : 0;
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
switch (ch) {
case '<': {
str.append("<");
break;
}
case '>': {
str.append(">");
break;
}
case '&': {
str.append("&");
break;
}
case '"': {
str.append(""");
break;
}
case '\r':
case '\n': {
if (canonical) {
str.append("&#");
str.append(Integer.toString(ch));
str.append(';');
break;
}
// else, default append char
}
default: {
str.append(ch);
}
}
}
return str.toString();
}
//============================================================
// Private method that returns a sorted list of attributes.
//
// This code was adapted from the sample code "DOMWriter.java"
// included with XML4J.
//============================================================
private static 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;
}
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