Module: xml-internals Synopsis: XML parser and printer Author: Scott McKay Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// XML printer define sealed method print-xml-to-file (xml :: , file :: ) => () with-open-file (stream = file, direction: #"output") print-xml-to-stream(xml, stream) end end method print-xml-to-file; define sealed method print-xml-to-string (xml :: ) => (string :: ) with-output-to-string (stream) print-xml-to-stream(xml, stream) end end method print-xml-to-string; define sealed generic print-xml-to-stream (xml :: , stream :: ) => (); define thread variable *printing-markup?* :: = #f; define sealed method print-xml-to-stream (document :: , stream :: ) => () write(stream, ""); new-line(stream); //---*** Shouldn't doctype just be one of the children? when (doctype(document)) print-xml-to-stream(doctype(document), stream) end; for (child in child-nodes(document)) print-xml-to-stream(child, stream) end; new-line(stream) end method print-xml-to-stream; define sealed method print-xml-to-stream (fragment :: , stream :: ) => () for (child in child-nodes(fragment)) print-xml-to-stream(child, stream) end; when (node-type(parent-node(fragment)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-to-stream (doctype :: , stream :: ) => () let docelt = document-element(owner-document(doctype)); write(stream, ""); when (node-type(parent-node(doctype)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-to-stream (elt :: , stream :: ) => () write(stream, "<"); dynamic-bind (*printing-markup?* = #t) print-xml-string(tag-name(elt), stream); let attributes :: = attributes(elt); for (i :: from 0 below length(attributes)) let attribute :: = item(attributes, i); when (specified?(attribute)) write(stream, " "); print-xml-to-stream(attribute, stream) end end end; //--- Is this the right test to decide whether to use ''? if (~has-child-nodes?(elt)) write(stream, "/>"); else write(stream, ">"); for (child in child-nodes(elt)) print-xml-to-stream(child, stream) end; write(stream, "") end end method print-xml-to-stream; // Note this simply won't get called if 'specified?' is false //---*** What about default values? define sealed method print-xml-to-stream (attr :: , stream :: ) => () dynamic-bind (*printing-markup?* = #t) print-xml-string(name(attr), stream); write(stream, "=\""); print-xml-string(value(attr), stream); write(stream, "\"") end end method print-xml-to-stream; define sealed method print-xml-to-stream (text :: , stream :: ) => () print-xml-string(data(text), stream) end method print-xml-to-stream; define sealed method print-xml-to-stream (cdata :: , stream :: ) => () write(stream, ""); end method print-xml-to-stream; define sealed method print-xml-to-stream (comment :: , stream :: ) => () write(stream, ""); when (node-type(parent-node(comment)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-to-stream (entity :: , stream :: ) => () write(stream, ""); when (node-type(parent-node(entity)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-to-stream (ref :: , stream :: ) => () write(stream, "&"); write(stream, node-name(ref)); write(stream, ";") end method print-xml-to-stream; define sealed method print-xml-to-stream (notation :: , stream :: ) => () write(stream, ""); when (node-type(parent-node(notation)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-to-stream (instr :: , stream :: ) => () write(stream, ""); when (node-type(parent-node(instr)) = $document-node) new-line(stream) end end method print-xml-to-stream; define sealed method print-xml-string (string :: , stream :: ) => () without-bounds-checks for (i :: from 0 below size(string)) let char :: = string[i]; case *printing-markup?* & char == '"' => write(stream, """); char == '<' => write(stream, "<"); char == '>' => write(stream, ">"); char == '&' => write(stream, "&"); otherwise => write-element(stream, char); end end end end method print-xml-string; define sealed method print-xml-string (char :: , stream :: ) => () case *printing-markup?* & char == '"' => write(stream, """); char == '<' => write(stream, "<"); char == '>' => write(stream, ">"); char == '&' => write(stream, "&"); otherwise => write-element(stream, char); end end method print-xml-string;