cziegeler 02/04/02 06:13:35 Modified: . changes.xml src/java/org/apache/cocoon/xml XMLUtils.java src/scratchpad/src/org/apache/cocoon/sunshine/xml XMLUtil.java Added: src/java/org/apache/cocoon/transformation AbstractSAXTransformer.java src/java/org/apache/cocoon/transformation/helpers NOPRecorder.java ParametersRecorder.java TextRecorder.java Log: Added AbstractSAXTransformer Revision Changes Path 1.134 +15 -11 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.133 retrieving revision 1.134 diff -u -r1.133 -r1.134 --- changes.xml 27 Mar 2002 15:13:40 -0000 1.133 +++ changes.xml 2 Apr 2002 14:13:34 -0000 1.134 @@ -1,10 +1,10 @@ -<?xml version="1.0"?> +<?xml version="1.0"?> <!DOCTYPE changes PUBLIC "-//APACHE//DTD Changes V1.0//EN" "src/documentation/xdocs/dtd/changes-v10.dtd"> <!-- History of Cocoon changes - $Id: changes.xml,v 1.133 2002/03/27 15:13:40 sylvain Exp $ + $Id: changes.xml,v 1.134 2002/04/02 14:13:34 cziegeler Exp $ --> <changes title="History of Changes"> @@ -35,6 +35,10 @@ </devs> <release version="@version@" date="@date@"> + <action dev="CZ" type="add"> + Added AbstractSAXTransformer for much easier implementation of custom + transformers. + </action> <action dev="SW" type="add"> Handle request forwarding (aka internal redirects) using the "cocoon:" pseudo-protocol : writing <map:redirect-to uri="cocoon:/foo.bar"/> makes @@ -177,7 +181,7 @@ super-fast load times (no more compilation), and a slight gain in request processing speed compared to the compiled engine thanks to the HotSpot VM. </action> - <action dev="VG" type="add"> + <action dev="VG"?type="add"> Added matchers: HeaderMatcher, ParameterMatcher. </action> <action dev="VG" type="add" due-to="Matteo Di Giovinazzo" due-to-email="[EMAIL PROTECTED]"> @@ -270,7 +274,7 @@ SitemapComponentSelector to store label information provided in the configuration. </action> - <action dev="GR" type="add"> + <action dev="?R" type="add"> Added the XPath-enabled DirectoryGenerator (XPathDirectoryGenerator) to scratchpad. </action> @@ -354,7 +358,7 @@ (1) removed the FilesystemQueueImpl, one thread less now, (2) changed swapping alghorithm in the MRUMemoryStore towards less serialization, (3) Cache entries will be saved to the filesystem, when the System is shutdown cleanly, (4) fixed - bug submitted by Peter Hargreaves [[EMAIL PROTECTED]] in StoreJanitor + bug submitted by Peter Har?reaves [[EMAIL PROTECTED]] in StoreJanitor (GC hangs in endless loop). </action> <action dev="VG" type="update"> @@ -442,7 +446,7 @@ <action dev="CZ" type="add"> Added special lifecycle interface for Cocoon components: RequestLifecycle. A component marked by this interface has the lifecycle of one request, - so looking up the role twice during the same request results in the same + so looking up the role twi?e during the same request results in the same component. </action> <action dev="SW" type="update"> @@ -513,7 +517,7 @@ Added RTF serialization of XSL-FO documents (requires jfor). Patch submitted by Bertrand Delacretaz [[EMAIL PROTECTED]]. Applied patch for the SQLTransformer to output namespaces for the - generated elements. Patch submitted by Per-Olof Nor謠[[EMAIL PROTECTED]]. + generated elements. Patch submitted by Per-Olof Nor?[[EMAIL PROTECTED]]. </action> <action dev="SW" type="add"> New ServerPagesAction and associated "action" and "capture" logicsheets @@ -539,7 +543,7 @@ </action> <action dev="CZ" type="update"> Applied patch for the SQLTransformer to output namespaces for the - generated elements. Patch submitted by Per-Olof Nor謠[[EMAIL PROTECTED]]. + generated elements. Patch submitted by Per-Olof Nor?[[EMAIL PROTECTED]]. </action> <action dev="OP" type="update"> Applied patch for incremental XSLT processing from Jörn Heid @@ -710,7 +714,7 @@ works for site of any complexity (limited by capabilities of your filesystem). </action> - <action dev="CZ" type="add"> + <action dev="CZ" type="add?> Removed XInclude/CIncludeSAXConnectors and added LoggingSAXConnector. </action> <action dev="CZ" type="add"> @@ -802,7 +806,7 @@ </action> <action dev="GP" type="add"> Enable a parallel calling path into the sitemap for internal requests - of resource. + of resource? </action> <action dev="GP" type="fix"> Added missing methods on CommandLineRequest. @@ -902,7 +906,7 @@ <action dev="DB" type="fix"> patched xsp generator to use proper namespace for automatic text elements </action> - <action dev="BL" type="update"> + <acti?n dev="BL" type="update"> Updated Cocoon to be Avalon 3.0a4 compliant. Introduced ComponentManager and ComponentSelector patterns correctly in code. Updated sitemap to create Configuration trees directly. 1.1 xml-cocoon2/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java Index: AbstractSAXTransformer.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.transformation; import java.io.*; import java.util.*; import org.apache.avalon.excalibur.source.SourceParameters; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.excalibur.pool.Recyclable; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.environment.Context; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Response; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.transformation.helpers.*; import org.apache.cocoon.xml.IncludeXMLConsumer; import org.apache.cocoon.xml.XMLConsumer; import org.apache.cocoon.xml.XMLUtils; import org.apache.cocoon.xml.dom.DOMBuilder; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** * This class is the basis for all transformers. It provides various useful * methods and hooks for implementing own custom transformers.<p> * <p> * The basic behaviour of each transformer consists of the following four parts: * <ul> * <li>Listen for specific events with a given namespace</li> * <li>Collect information via these events</li> * <li>Process the information</li> * <li>Create new events from the processed information</li> * </ul><p> * For all these four purposes the AbstractSunshineTransformer offers some * powerful methods and hooks: * <p> * Namespace handling<p> * By setting the instance variable namespaceURI to the namespace the * events are filtered and only events with this namespace are send to * the two hooks startTransformingElement() and endTransformingElement().<p> * It is possible to override the default * namespace for the transformer by specifying the parameter "namespaceURI" * in the pipeline. This avoids possible namespace collisions.<p> * * Recording of information<p> * There are several methods for recording information, e.g. startRecording(), * startTextRecording() etc. These methods collect information from the xml * stream for further processing.<p> * * Creating new events<p> * New events can be easily created with the <code>sendEvents()</code> * method, the <code>sendStartElementEvent()</code> methods, the <code>sendEndElementEvent()</code> * method or the <code>sendTextEvent()</code> method.<p> * * Initialization<p> * Before the document is processed the setupTransforming() hook is invoked. * * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Id: AbstractSAXTransformer.java,v 1.1 2002/04/02 14:13:34 cziegeler Exp $ */ public abstract class AbstractSAXTransformer extends AbstractTransformer implements Composable, Configurable, Recyclable { /** Controlls SAX event handling. * If set to true all whitespace events are ignored. */ protected boolean ignoreWhitespaces; /** Controlls SAX event handling * If set to true all characters events containing only whitespaces * are ignored. */ protected boolean ignoreEmptyCharacters; /** Controlls SAX event handling * If this is incremented all events are not forwarded to the next * pipeline component, but the hooks are still called. */ protected int ignoreEventsCount; /** Controlls SAX event handling * If this is greater than zero, the hooks are not called. Attention, * make sure, that you decrement this counter properly as your hooks are * not called anymore! */ protected int ignoreHooksCount; /** * The used namespace for the SAX filtering. * This is either the defaultNamespaceURI or the value * set by the "namespaceURI" parameter for the pipeline. */ protected String namespaceURI; /** * This is the default namespace used by the transformer. * It should be set by in the constructor. */ protected String defaultNamespaceURI; /** A stack for collecting information. * The stack is important for collection information especially when * the tags can be nested. */ protected Stack stack = new Stack(); /** The stack of current used recorders */ protected Stack recorderStack = new Stack(); /** The current Request object */ protected Request request; /** The current Response object */ protected Response response; /** The current Context object */ protected Context context; /** The current objectModel of the environment */ protected Map objectModel; /** The parameters specified in the sitemap */ protected Parameters parameters; /** The source attribute specified in the sitemap */ protected String source; /** The Avalon ComponentManager for getting Components */ protected ComponentManager manager; /** The SourceResolver for this request */ protected SourceResolver resolver; /** Empty attributes (for performance). This can be used * do create own attributes, but make sure to clean them * afterwords. */ protected AttributesImpl emptyAttributes = new AttributesImpl(); /** The namespaces */ private List namespaces = new ArrayList(5); /** * Avalon Configurable Interface */ public void configure(Configuration configuration) throws ConfigurationException { } /** * Setup the next round. * The instance variables are initialised. * @param resolver The current SourceResolver * @param objectModel The objectModel of the environment. * @param src The value of the src attribute in the sitemap. * @param par The parameters from the sitemap. */ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN setup resolver="+resolver+ ", objectModel="+objectModel+ ", src="+src+ ", parameters="+par); } if (this.defaultNamespaceURI == null) { this.defaultNamespaceURI = this.namespaceURI; } this.objectModel = objectModel; this.request = ObjectModelHelper.getRequest(objectModel); this.response = ObjectModelHelper.getResponse(objectModel); this.context = ObjectModelHelper.getContext(objectModel); this.resolver = resolver; this.parameters = par; this.source = src; // get the current namespace this.namespaceURI = this.parameters.getParameter("namespaceURI", this.defaultNamespaceURI); this.ignoreHooksCount = 0; this.ignoreEventsCount = 0; this.ignoreWhitespaces = true; this.ignoreEmptyCharacters = false; if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END setup"); } } /** * Recycle this component. */ public void recycle() { super.recycle(); this.objectModel = null; this.request = null; this.response = null; this.context = null; this.resolver = null; this.stack.clear(); this.recorderStack.clear(); this.parameters = null; this.source = null; this.namespaces.clear(); } /** * Avalon Composable Interface * @param manager The Avalon Component Manager */ public void compose(ComponentManager manager) { this.manager = manager; } /** * Process the SAX event. A new document is processed. The hook (method) * <code>setupTransforming()</code> is invoked. * @see org.xml.sax.ContentHandler#startDocument */ public void startDocument() throws SAXException { try { this.setupTransforming(); } catch (ProcessingException local) { throw new SAXException("ProcessingException: " + local, local); } catch (IOException ioe) { throw new SAXException("IOException: " + ioe, ioe); } if (this.ignoreEventsCount == 0) super.startDocument(); } /** * Process the SAX event. The processing of the document is finished. * @see org.xml.sax.ContentHandler#endDocument */ public void endDocument() throws SAXException { if (this.ignoreEventsCount == 0) super.endDocument(); } /** * Process the SAX event. * The namespace of the event is checked. If it is the defined namespace * for this transformer the startTransformingElement() hook is called. */ public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException { if (uri != null && namespaceURI != null && uri.equals(namespaceURI) == true && this.ignoreHooksCount == 0) { // this is our namespace: try { this.startTransformingElement(uri, name, raw, attr); } catch (ProcessingException sunShineException) { throw new SAXException("ProcessingException: " + sunShineException, sunShineException); } catch (IOException ioe) { throw new SAXException("Exception occured during processing: " + ioe, ioe); } } else { if (ignoreEventsCount == 0) super.startElement(uri, name, raw, attr); } } /** * Process the SAX event. * The namespace of the event is checked. If it is the defined namespace * for this transformer the endTransformingElement() hook is called. */ public void endElement(String uri, String name, String raw) throws SAXException { if (uri != null && namespaceURI != null && uri.equals(namespaceURI) == true && this.ignoreHooksCount == 0) { // this is our namespace: try { this.endTransformingElement(uri, name, raw); } catch (ProcessingException sunShineException) { throw new SAXException("ProcessingException: " + sunShineException, sunShineException); } catch (IOException ioe) { throw new SAXException("Exception occured during processing: " + ioe, ioe); } } else { if (ignoreEventsCount == 0) super.endElement(uri, name, raw); } } /** * Process the SAX event. */ public void characters(char[] p0, int p1, int p2) throws SAXException { if (this.ignoreEventsCount == 0) { if (this.ignoreEmptyCharacters == true) { String value = new String(p0, p1, p2); if (value.trim().length() > 0) { super.characters(p0, p1, p2); } } else { super.characters(p0, p1, p2); } } } /** * Process the SAX event. */ public void ignorableWhitespace(char[] p0, int p1, int p2) throws SAXException { if (ignoreWhitespaces == false && ignoreEventsCount == 0) super.ignorableWhitespace(p0, p1, p2); } /* * Recording of events. * With this method all events are not forwarded to the next component in the pipeline. * They are recorded to create a document fragment. */ private LexicalHandler originalLexicalHandler; private ContentHandler originalContentHandler; /** * Add a new recorder to the recording chain. * Do not invoke this method directly. */ protected void addRecorder(XMLConsumer recorder) { if (this.recorderStack.empty() == true) { // redirect if first (top) recorder this.originalLexicalHandler = this.lexicalHandler; this.originalContentHandler = this.contentHandler; } this.setContentHandler(recorder); this.setLexicalHandler(recorder); this.recorderStack.push(recorder); } /** * Remove a recorder from the recording chain. * Do not invoke this method directly. */ protected Object removeRecorder() { Object recorder = this.recorderStack.pop(); if (this.recorderStack.empty() == true) { // undo redirect if no recorder any more this.setContentHandler(originalContentHandler); this.setLexicalHandler(originalLexicalHandler); this.originalLexicalHandler = null; this.originalContentHandler = null; } else { XMLConsumer next = (XMLConsumer)recorderStack.peek(); this.setContentHandler(next); this.setLexicalHandler(next); } return recorder; } /** * Start DocumentFragment recording. * All invoming events are recorded and not forwarded. The resulting * DocumentFragment can be obtained by the matching endRecording() call. */ public void startRecording() throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN startRecording"); } DOMBuilder builder = new DOMBuilder(); this.addRecorder(builder); builder.startDocument(); builder.startElement("", "sunShine", "sunShine", new AttributesImpl()); this.sendStartPrefixMapping(); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END startRecording"); } } /** * Stop DocumentFragment recording. * All invoming events are recorded and not forwarded. This method returns * the resulting DocumentFragment. */ public DocumentFragment endRecording() throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endRecording"); } this.sendEndPrefixMapping(); DOMBuilder builder = (DOMBuilder)this.removeRecorder(); builder.endElement("", "sunShine", "sunShine"); builder.endDocument(); // Create Document Fragment final Document doc = builder.getDocument(); final DocumentFragment recordedDocFrag = doc.createDocumentFragment(); final Node root = doc.getDocumentElement(); root.normalize(); Node child; boolean appendedNode = false; while (root.hasChildNodes() == true) { child = root.getFirstChild(); root.removeChild(child); // Leave out empty text nodes before any other node if (appendedNode == true || child.getNodeType() != Node.TEXT_NODE || child.getNodeValue().trim().length() > 0) { recordedDocFrag.appendChild(child); appendedNode = true; } } if (this.getLogger().isDebugEnabled() == true) { Object serializedXML = null; try { serializedXML = (recordedDocFrag == null ? "null" : XMLUtils.serializeNodeToXML(recordedDocFrag)); } catch (ProcessingException ignore) { serializedXML = recordedDocFrag; } this.getLogger().debug("END endRecording fragment=" + serializedXML); } return recordedDocFrag; } /** * Start recording of text. * All events are not forwarded and the characters events * are merged to a string */ public void startTextRecording() throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN startTextRecording"); } XMLConsumer recorder = new TextRecorder(); this.addRecorder(recorder); this.sendStartPrefixMapping(); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END startTextRecording"); } } /** * Stop recording of text and return the recorded information. * @return The String. */ public String endTextRecording() throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endTextRecording"); } this.sendEndPrefixMapping(); TextRecorder recorder = (TextRecorder)this.removeRecorder(); String text = recorder.getText(); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END endTextRecording text="+text); } return text; } /** * Start recording of serialized xml * All events are converted to an xml string which can be retrieved by * endSerializedXMLRecording. * @param format The format for the serialized output. If <CODE>null</CODE> * is specified, the default format is used. */ public void startSerializedXMLRecording(Properties format) throws SAXException, IOException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN startSerializedXMLRecording format="+format); } this.stack.push((format == null ? XMLUtils.defaultSerializeToXMLFormat() : format)); this.startRecording(); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END startSerializedXMLRecording"); } } /** * Return the serialized xml string. * @return A string containing the recorded xml information, formatted by * the properties passed to the corresponding startSerializedXMLRecording(). */ public String endSerializedXMLRecording() throws SAXException, ProcessingException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endSerializedXMLRecording"); } DocumentFragment fragment = this.endRecording(); String text = XMLUtils.serializeNode(fragment, (Properties)this.stack.pop()); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END endSerializedXMLRecording xml="+text); } return text; } /** * Start recording of parameters. * All events are not forwarded and the incoming xml is converted to * parameters. Each toplevel node is a parameter and its text subnodes * form the value. * The Parameters can eiter be retrieved by endParametersRecording(). */ public void startParametersRecording() throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN startParametersRecording"); } XMLConsumer recorder = new ParametersRecorder(); this.addRecorder(recorder); this.sendStartPrefixMapping(); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END startParametersRecording"); } } /** * End recording of parameters * If source is null a new parameters object is created, otherwise * the parameters are added to this object. * @param source An optional parameters object. * @return The object containing all parameters. */ public SourceParameters endParametersRecording(Parameters source) throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endParametersRecording source="+source); } this.sendEndPrefixMapping(); ParametersRecorder recorder = (ParametersRecorder)this.removeRecorder(); SourceParameters pars = recorder.getParameters(source); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END endParametersRecording parameters="+pars); } return pars; } /** * End recording of parameters * If source is null a new parameters object is created, otherwise * the parameters are added to this object. * @param source An optional parameters object. * @return The object containing all parameters. */ public SourceParameters endParametersRecording(SourceParameters source) throws SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endParametersRecording source="+source); } this.sendEndPrefixMapping(); ParametersRecorder recorder = (ParametersRecorder)this.removeRecorder(); SourceParameters pars = recorder.getParameters(source); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END endParametersRecording parameters="+pars); } return pars; } // ************ // Hooks // ************ /** * Setup the transformation of an xml document. * This method is called just before the transformation (sending of sax events) * starts. It should be used to initialize setup parameter depending on the * object modell. */ public void setupTransforming() throws IOException, ProcessingException, SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN setupTransforming"); } this.stack.clear(); this.recorderStack.clear(); this.ignoreWhitespaces = true; this.ignoreEmptyCharacters = false; if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END setupTransforming"); } } /** * Start processing elements of our namespace. * This hook is invoked for each sax event with our namespace. * @param uri The namespace of the element. * @param name The local name of the element. * @param raw The qualified name of the element. * @param attr The attributes of the element. */ public void startTransformingElement(String uri, String name, String raw, Attributes attr) throws ProcessingException, IOException, SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN startTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw + ", attr=" + attr + ")"); } if (this.ignoreEventsCount == 0) super.startElement(uri, name, raw, attr); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END startTransformingElement"); } } /** * Start processing elements of our namespace. * This hook is invoked for each sax event with our namespace. * @param uri The namespace of the element. * @param name The local name of the element. * @param raw The qualified name of the element. */ public void endTransformingElement(String uri, String name, String raw) throws ProcessingException, IOException, SAXException { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw + ")"); } if (this.ignoreEventsCount == 0) super.endElement(uri, name, raw); if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("END endTransformingElement"); } } /** * Send SAX events to the next pipeline component. * The characters event for the given text is send to the next * component in the current pipeline. * @param text The string containing the information. */ public void sendTextEvent(String text) throws SAXException { this.characters(text.toCharArray(), 0, text.length()); } /** * Send SAX events to the next pipeline component. * The startElement event for the given element is send * to the next component in the current pipeline. * The element has no namespace and no attributes * @param localname The name of the event. */ public void sendStartElementEvent(String localname) throws SAXException { this.startElement("", localname, localname, emptyAttributes); } /** * Send SAX events to the next pipeline component. * The startElement event for the given element is send * to the next component in the current pipeline. * The element has no namespace. * @param localname The name of the event. * @param attr The Attributes of the element */ public void sendStartElementEvent(String localname, Attributes attr) throws SAXException { this.startElement("", localname, localname, attr); } /** * Send SAX events to the next pipeline component. * The endElement event for the given element is send * to the next component in the current pipeline. * The element has no namespace. * @param localname The name of the event. */ public void sendEndElementEvent(String localname) throws SAXException { this.endElement("", localname, localname); } /** * Send SAX events to the next pipeline component. * The node is parsed and the events are send to * the next component in the pipeline. * @param node The tree to be included. */ public void sendEvents(Node node) throws SAXException { IncludeXMLConsumer.includeNode(node, this, this); } /** * Send SAX events for the <code>SourceParameters</code>. * For each parametername/value pair an element is * created with the name of the parameter and the content * of this element is the value. */ public void sendParametersEvents(SourceParameters pars) throws SAXException { if (pars != null) { Iterator names = pars.getParameterNames(); String currentName; String currentValue; Iterator values; while (names.hasNext() == true) { currentName = (String)names.next(); values = pars.getParameterValues(currentName); while (values.hasNext() == true) { currentValue = (String)values.next(); this.sendStartElementEvent(currentName); this.sendTextEvent(currentValue); this.sendEndElementEvent(currentName); } } } } /** * SAX Event handling */ public void startEntity (String name) throws SAXException { if (this.ignoreEventsCount == 0) super.startEntity(name); } /** * SAX Event handling */ public void endEntity (String name) throws SAXException { if (this.ignoreEventsCount == 0) super.endEntity(name); } /** * Send all start prefix mapping events to the current content handler */ protected void sendStartPrefixMapping() throws SAXException { int i,l; l = this.namespaces.size(); String[] prefixAndUri; for(i=0; i<l; i++) { prefixAndUri = (String[])this.namespaces.get(i); super.contentHandler.startPrefixMapping(prefixAndUri[0], prefixAndUri[1]); } } /** * Send all end prefix mapping events to the current content handler */ protected void sendEndPrefixMapping() throws SAXException { int i,l; l = this.namespaces.size(); String[] prefixAndUri; for(i=0; i<l; i++) { prefixAndUri = (String[])this.namespaces.get(i); super.contentHandler.endPrefixMapping(prefixAndUri[0]); } } /** * SAX Event handling */ public void setDocumentLocator(Locator locator) { if (this.ignoreEventsCount == 0) super.setDocumentLocator(locator); } /** * SAX Event handling */ public void startPrefixMapping(String prefix, String uri) throws SAXException { if (prefix != null) this.namespaces.add(new String[] {prefix, uri}); if (this.ignoreEventsCount == 0) super.startPrefixMapping(prefix, uri); } /** * SAX Event handling */ public void endPrefixMapping(String prefix) throws SAXException { if (prefix != null) { // search the namespace prefix boolean found = false; int l = this.namespaces.size(); int i = l-1; String currentPrefix; while (found == false && i >= 0) { currentPrefix = ((String[])this.namespaces.get(i))[0]; if (currentPrefix.equals(prefix) == true) { found = true; } else { i--; } } if (found == false) { throw new SAXException("Namespace for prefix '"+ prefix + "' not found."); } this.namespaces.remove(i); } if (this.ignoreEventsCount == 0) super.endPrefixMapping(prefix); } /** * SAX Event handling */ public void processingInstruction(String target, String data) throws SAXException { if (this.ignoreEventsCount == 0) super.processingInstruction(target, data); } /** * SAX Event handling */ public void skippedEntity(String name) throws SAXException { if (this.ignoreEventsCount == 0) super.skippedEntity(name); } /** * SAX Event handling */ public void startDTD(String name, String public_id, String system_id) throws SAXException { if (this.ignoreEventsCount == 0) super.startDTD(name, public_id, system_id); } /** * SAX Event handling */ public void endDTD() throws SAXException { if (this.ignoreEventsCount == 0) super.endDTD(); } /** * SAX Event handling */ public void startCDATA() throws SAXException { if (this.ignoreEventsCount == 0) super.startCDATA(); } /** * SAX Event handling */ public void endCDATA() throws SAXException { if (this.ignoreEventsCount == 0) super.endCDATA(); } /** * SAX Event handling */ public void comment(char ary[], int start, int length) throws SAXException { if (this.ignoreEventsCount == 0) super.comment(ary, start, length); } } 1.1 xml-cocoon2/src/java/org/apache/cocoon/transformation/helpers/NOPRecorder.java Index: NOPRecorder.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.transformation.helpers; import org.apache.cocoon.xml.XMLConsumer; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; /** * The base class for all recorders. Simply does nothing * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Id: NOPRecorder.java,v 1.1 2002/04/02 14:13:34 cziegeler Exp $ */ public abstract class NOPRecorder implements ContentHandler, LexicalHandler, XMLConsumer { public NOPRecorder() { } public void setDocumentLocator(Locator locator) { } public void startDocument() throws SAXException { } public void endDocument() throws SAXException { } public void startPrefixMapping(String prefix, String uri) throws SAXException { } public void endPrefixMapping(String prefix) throws SAXException { } public void startElement(String namespace, String name, String raw, Attributes attr) throws SAXException { } public void endElement(String namespace, String name, String raw) throws SAXException { } public void characters(char ary[], int start, int length) throws SAXException { } public void ignorableWhitespace(char ary[], int start, int length) throws SAXException { } public void processingInstruction(String target, String data) throws SAXException { } public void skippedEntity(String name) throws SAXException { } public void startDTD(String name, String public_id, String system_id) throws SAXException { } public void endDTD() throws SAXException { } public void startEntity(String name) throws SAXException { } public void endEntity(String name) throws SAXException { } public void startCDATA() throws SAXException { } public void endCDATA() throws SAXException { } public void comment(char ary[], int start, int length) throws SAXException { } } 1.1 xml-cocoon2/src/java/org/apache/cocoon/transformation/helpers/ParametersRecorder.java Index: ParametersRecorder.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.transformation.helpers; import java.util.Iterator; import java.util.Map; import org.apache.avalon.excalibur.source.SourceParameters; import org.apache.avalon.framework.parameters.Parameters; import org.xml.sax.Attributes; import org.xml.sax.SAXException; /** * This class records SAX Events and generates Parameters from them * The xml is flat and consists of elements which all have exactly one text node: * <parone>value_one<parone> * <partwo>value_two<partwo> * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Id: ParametersRecorder.java,v 1.1 2002/04/02 14:13:34 cziegeler Exp $ */ public final class ParametersRecorder extends NOPRecorder { private SourceParameters parameters; private String key; private StringBuffer buffer; /** * If source is null a new Parameters object is created * Otherwise they are joined. */ public ParametersRecorder() { super(); this.parameters = new SourceParameters(); } public SourceParameters getParameters(Parameters source) { if (source != null) { String[] names = source.getNames(); // Iterator names = source.getParameterNames(); if (names != null) { String currentParameterName; for(int i=0; i<names.length; i++) { currentParameterName = names[i]; // while (names.hasNext() == true) { // currentParameterName = (String)names.next(); this.parameters.setParameter(currentParameterName, source.getParameter(currentParameterName, "")); } } } return parameters; } public SourceParameters getParameters(SourceParameters source) { if (source != null) { Iterator iter = source.getParameterNames(); Iterator valuesIter; String value, parName; while (iter.hasNext() == true) { parName = (String)iter.next(); valuesIter = source.getParameterValues(parName); while (valuesIter.hasNext() == true) { value = (String)valuesIter.next(); this.parameters.setParameter(parName, value); } } } return parameters; } public void startElement(String namespace, String name, String raw, Attributes attr) throws SAXException { if (this.key == null) { this.key = name; this.buffer = new StringBuffer(); } } public void endElement(String namespace, String name, String raw) throws SAXException { if (this.key != null && this.key.equals(name) == true) { String value = this.buffer.toString().trim(); if (value.length() > 0) { this.parameters.setParameter(this.key, value); } this.buffer = null; this.key = null; } } public void characters(char ary[], int start, int length) throws SAXException { if (this.key != null && this.buffer != null) { String value = new String(ary, start, length).trim(); if (value.length() > 0) { buffer.append(value); } else { buffer.append(' '); } } } } 1.1 xml-cocoon2/src/java/org/apache/cocoon/transformation/helpers/TextRecorder.java Index: TextRecorder.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.transformation.helpers; import org.xml.sax.SAXException; /** * This class records SAX Events and generates a String from all * characters events * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Id: TextRecorder.java,v 1.1 2002/04/02 14:13:34 cziegeler Exp $ */ public final class TextRecorder extends NOPRecorder { public TextRecorder() { super(); } private StringBuffer buffer = new StringBuffer(); public void characters(char ary[], int start, int length) throws SAXException { String value = new String(ary, start, length).trim(); if (value.length() > 0) { buffer.append(value); } else { buffer.append(' '); } } public String getText() { return buffer.toString().trim(); } } 1.6 +76 -3 xml-cocoon2/src/java/org/apache/cocoon/xml/XMLUtils.java Index: XMLUtils.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/xml/XMLUtils.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- XMLUtils.java 22 Feb 2002 23:25:19 -0000 1.5 +++ XMLUtils.java 2 Apr 2002 14:13:34 -0000 1.6 @@ -50,7 +50,9 @@ */ package org.apache.cocoon.xml; +import java.io.StringWriter; import java.util.ArrayList; +import java.util.Properties; import org.w3c.dom.Attr; import org.w3c.dom.Document; @@ -62,12 +64,22 @@ import org.xml.sax.ContentHandler; import org.xml.sax.ext.LexicalHandler; +import org.apache.cocoon.ProcessingException; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + /** * XML utility methods. * * @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Id: XMLUtils.java,v 1.5 2002/02/22 23:25:19 sylvain Exp $ + * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> + * @version CVS $Id: XMLUtils.java,v 1.6 2002/04/02 14:13:34 cziegeler Exp $ */ public class XMLUtils{ @@ -131,7 +143,7 @@ break; } } - + /** * Get an <code>XMLConsumer</code> from a <code>ContentHandler</code> and * a <code>LexicalHandler</code>. If the content handler is already an @@ -148,7 +160,7 @@ else return new ContentHandlerWrapper(ch, lh); } - + /** * Get an <code>XMLConsumer</code> from <code>ContentHandler</code>. If the * content handler is already an <code>XMLConsumer</code>, it is returned as @@ -160,4 +172,65 @@ public static XMLConsumer getConsumer(ContentHandler ch) { return getConsumer(ch, null); } + + /** + * Serialize a DOM node to a String. + * The defaultSerializeToXMLFormat() is used to format the serialized xml. + */ + public static String serializeNodeToXML(Node node) + throws ProcessingException { + return serializeNode(node, XMLUtils.defaultSerializeToXMLFormat()); + } + + /** + * This is the default properties set used to serialize xml. + * It is used by the serializeNodeToXML() method. + * The format is as follows: + * Method: xml + * Encoding: ISO-8859-1 + * Omit xml declaration: no + * Indent: yes + */ + public static Properties defaultSerializeToXMLFormat() { + return defaultSerializeToXMLFormat(false); + } + + /** + * This is the default properties set used to serialize xml. + * It is used by the serializeNodeToXML() method. + * The omit xml declaration property can be controlled by the flag. + * Method: xml + * Encoding: ISO-8859-1 + * Omit xml declaration: according to the flag + * Indent: yes + */ + public static Properties defaultSerializeToXMLFormat(boolean omitXMLDeclaration) { + Properties format = new Properties(); + format.put(OutputKeys.METHOD, "xml"); + format.put(OutputKeys.ENCODING, "ISO-8859-1"); + format.put(OutputKeys.OMIT_XML_DECLARATION, (omitXMLDeclaration ? "yes" : "no")); + format.put(OutputKeys.INDENT, "yes"); + return format; + } + + /** + * Serialize a DOM node to a String. + * The format of the output can be specified with the properties. + * If the node is null the empty string is returned. + */ + public static String serializeNode(Node node, Properties format) + throws ProcessingException { + try { + if (node == null) return ""; + StringWriter writer = new StringWriter(); + Transformer transformer; + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperties(format); + transformer.transform(new DOMSource(node), new StreamResult(writer)); + return writer.toString(); + } catch (javax.xml.transform.TransformerException local) { + throw new ProcessingException("TransformerException: " + local, local); + } + } + } 1.8 +1 -60 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/sunshine/xml/XMLUtil.java Index: XMLUtil.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/sunshine/xml/XMLUtil.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- XMLUtil.java 28 Mar 2002 15:25:05 -0000 1.7 +++ XMLUtil.java 2 Apr 2002 14:13:35 -0000 1.8 @@ -95,7 +95,7 @@ * @deprecated Do not use this class! We will provide a better solution for most methods soon. * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> - * @version CVS $Id: XMLUtil.java,v 1.7 2002/03/28 15:25:05 cziegeler Exp $ + * @version CVS $Id: XMLUtil.java,v 1.8 2002/04/02 14:13:35 cziegeler Exp $ */ public final class XMLUtil { @@ -568,65 +568,6 @@ return value.toString().trim(); } - /** - * Serialize a DOM node to a String. - * The defaultSerializeToXMLFormat() is used to format the serialized xml. - */ - public static String serializeNodeToXML(Node node) - throws ProcessingException { - return serializeNode(node, XMLUtil.defaultSerializeToXMLFormat()); - } - - /** - * This is the default properties set used to serialize xml. - * It is used by the serializeNodeToXML() method. - * The format is as follows: - * Method: xml - * Encoding: ISO-8859-1 - * Omit xml declaration: no - * Indent: yes - */ - public static Properties defaultSerializeToXMLFormat() { - return defaultSerializeToXMLFormat(false); - } - - /** - * This is the default properties set used to serialize xml. - * It is used by the serializeNodeToXML() method. - * The omit xml declaration property can be controlled by the flag. - * Method: xml - * Encoding: ISO-8859-1 - * Omit xml declaration: according to the flag - * Indent: yes - */ - public static Properties defaultSerializeToXMLFormat(boolean omitXMLDeclaration) { - Properties format = new Properties(); - format.put(OutputKeys.METHOD, "xml"); - format.put(OutputKeys.ENCODING, "ISO-8859-1"); - format.put(OutputKeys.OMIT_XML_DECLARATION, (omitXMLDeclaration ? "yes" : "no")); - format.put(OutputKeys.INDENT, "yes"); - return format; - } - - /** - * Serialize a DOM node to a String. - * The format of the output can be specified with the properties. - * If the node is null the empty string is returned. - */ - public static String serializeNode(Node node, Properties format) - throws ProcessingException { - try { - if (node == null) return ""; - Writer writer = new StringWriter(); - Transformer transformer; - transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperties(format); - transformer.transform(new DOMSource(node), new StreamResult(writer)); - return writer.toString(); - } catch (javax.xml.transform.TransformerException local) { - throw new ProcessingException("TransformerException: " + local, local); - } - } /** * Create a new empty DOM document.
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]