19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: TreeWalker.java 468654 2006-10-28 07:09:23Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.serializer;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.File;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.AttList;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.DOM2Helper;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Comment;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Element;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.EntityReference;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.NamedNodeMap;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.ProcessingInstruction;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Text;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ContentHandler;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Locator;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ext.LexicalHandler;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.helpers.LocatorImpl;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class does a pre-order walk of the DOM tree, calling a ContentHandler
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * interface as it goes.
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class is a copy of the one in org.apache.xml.utils.
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It exists to cut the serializers dependancy on that package.
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic final class TreeWalker
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Local reference to a ContentHandler          */
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  final private ContentHandler m_contentHandler;
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If m_contentHandler is a SerializationHandler, then this is
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a reference to the same object.
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  final private SerializationHandler m_Serializer;
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // ARGHH!!  JAXP Uses Xerces without setting the namespace processing to ON!
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // DOM2Helper m_dh = new DOM2Helper();
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** DomHelper for this TreeWalker          */
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  final protected DOM2Helper m_dh;
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Locator object for this TreeWalker          */
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  final private LocatorImpl m_locator = new LocatorImpl();
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the ContentHandler used for the tree walk.
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the ContentHandler used for the tree walk
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ContentHandler getContentHandler()
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_contentHandler;
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public TreeWalker(ContentHandler ch) {
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this(ch,null);
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Constructor.
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param   contentHandler The implemention of the
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * contentHandler operation (toXMLString, digest, ...)
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public TreeWalker(ContentHandler contentHandler, String systemId)
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Set the content handler
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_contentHandler = contentHandler;
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_contentHandler instanceof SerializationHandler) {
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_Serializer = (SerializationHandler) m_contentHandler;
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_Serializer = null;
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Set the system ID, if it is given
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_contentHandler.setDocumentLocator(m_locator);
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (systemId != null)
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_locator.setSystemId(systemId);
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          try {
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Bug see Bugzilla  26741
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           }
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           catch (SecurityException se) {// user.dir not accessible from applet
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           }
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Set the document locator
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_contentHandler != null)
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_contentHandler.setDocumentLocator(m_locator);
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                try {
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   // Bug see Bugzilla  26741
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  m_locator.setSystemId(System.getProperty("user.dir") + File.separator + "dummy.xsl");
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                catch (SecurityException se){// user.dir not accessible from applet
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_dh = new DOM2Helper();
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Perform a pre-order traversal non-recursive style.
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note that TreeWalker assumes that the subtree is intended to represent
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a complete (though not necessarily well-formed) document and, during a
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * traversal, startDocument and endDocument will always be issued to the
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * SAX listener.
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pos Node in the tree where to start traversal
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void traverse(Node pos) throws org.xml.sax.SAXException
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this.m_contentHandler.startDocument();
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Node top = pos;
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (null != pos)
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      startNode(pos);
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Node nextNode = pos.getFirstChild();
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (null == nextNode)
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        endNode(pos);
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (top.equals(pos))
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextNode = pos.getNextSibling();
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == nextNode)
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pos = pos.getParentNode();
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ((null == pos) || (top.equals(pos)))
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (null != pos)
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              endNode(pos);
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nextNode = null;
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pos = nextNode;
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this.m_contentHandler.endDocument();
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Perform a pre-order traversal non-recursive style.
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note that TreeWalker assumes that the subtree is intended to represent
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a complete (though not necessarily well-formed) document and, during a
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * traversal, startDocument and endDocument will always be issued to the
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * SAX listener.
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pos Node in the tree where to start traversal
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param top Node in the tree where to end traversal
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void traverse(Node pos, Node top) throws org.xml.sax.SAXException
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this.m_contentHandler.startDocument();
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (null != pos)
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      startNode(pos);
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Node nextNode = pos.getFirstChild();
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (null == nextNode)
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        endNode(pos);
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((null != top) && top.equals(pos))
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextNode = pos.getNextSibling();
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == nextNode)
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pos = pos.getParentNode();
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ((null == pos) || ((null != top) && top.equals(pos)))
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nextNode = null;
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pos = nextNode;
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this.m_contentHandler.endDocument();
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Flag indicating whether following text to be processed is raw text          */
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  boolean nextIsRaw = false;
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Optimized dispatch of characters.
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private final void dispatachChars(Node node)
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     throws org.xml.sax.SAXException
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_Serializer != null)
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.m_Serializer.characters(node);
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String data = ((Text) node).getData();
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.m_contentHandler.characters(data.toCharArray(), 0, data.length());
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Start processing given node
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node Node to process
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws org.xml.sax.SAXException
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void startNode(Node node) throws org.xml.sax.SAXException
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//   TODO: <REVIEW>
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    A Serializer implements ContentHandler, but not NodeConsumer
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    so drop this reference to NodeConsumer which would otherwise
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    pull in all sorts of things
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    if (m_contentHandler instanceof NodeConsumer)
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    {
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//      ((NodeConsumer) m_contentHandler).setOriginatingNode(node);
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    }
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    TODO: </REVIEW>
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (node instanceof Locator)
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Locator loc = (Locator)node;
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_locator.setColumnNumber(loc.getColumnNumber());
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_locator.setLineNumber(loc.getLineNumber());
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_locator.setPublicId(loc.getPublicId());
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_locator.setSystemId(loc.getSystemId());
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        m_locator.setColumnNumber(0);
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_locator.setLineNumber(0);
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (node.getNodeType())
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.COMMENT_NODE :
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String data = ((Comment) node).getData();
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_contentHandler instanceof LexicalHandler)
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        lh.comment(data.toCharArray(), 0, data.length());
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.DOCUMENT_FRAGMENT_NODE :
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // ??;
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.DOCUMENT_NODE :
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.ELEMENT_NODE :
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Element elem_node = (Element) node;
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Make sure the namespace node
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // for the element itself is declared
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // to the ContentHandler
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          String uri = elem_node.getNamespaceURI();
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (uri != null) {
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              String prefix = elem_node.getPrefix();
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (prefix==null)
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                prefix="";
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              this.m_contentHandler.startPrefixMapping(prefix,uri);
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NamedNodeMap atts = elem_node.getAttributes();
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nAttrs = atts.getLength();
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // System.out.println("TreeWalker#startNode: "+node.getNodeName());
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Make sure the namespace node of
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // each attribute is declared to the ContentHandler
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < nAttrs; i++)
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final Node attr = atts.item(i);
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String attrName = attr.getNodeName();
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int colon = attrName.indexOf(':');
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String prefix;
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // System.out.println("TreeWalker#startNode: attr["+i+"] = "+attrName+", "+attr.getNodeValue());
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Use "" instead of null, as Xerces likes "" for the
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // name of the default namespace.  Fix attributed
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // to "Steven Murray" <smurray@ebt.com>.
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (colon < 0)
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = "";
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = attrName.substring(colon + 1);
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          this.m_contentHandler.startPrefixMapping(prefix,
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                   attr.getNodeValue());
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (colon > 0) {
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = attrName.substring(0,colon);
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String uri = attr.getNamespaceURI();
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (uri != null)
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                this.m_contentHandler.startPrefixMapping(prefix,uri);
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String ns = m_dh.getNamespaceOfNode(node);
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(null == ns)
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ns = "";
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.m_contentHandler.startElement(ns,
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         m_dh.getLocalNameOfNode(node),
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         node.getNodeName(),
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         new AttList(atts, m_dh));
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.PROCESSING_INSTRUCTION_NODE :
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ProcessingInstruction pi = (ProcessingInstruction) node;
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String name = pi.getNodeName();
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // String data = pi.getData();
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (name.equals("xslt-next-is-raw"))
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextIsRaw = true;
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        this.m_contentHandler.processingInstruction(pi.getNodeName(),
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                    pi.getData());
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.CDATA_SECTION_NODE :
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean isLexH = (m_contentHandler instanceof LexicalHandler);
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      LexicalHandler lh = isLexH
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                          ? ((LexicalHandler) this.m_contentHandler) : null;
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isLexH)
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        lh.startCDATA();
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      dispatachChars(node);
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (isLexH)
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          lh.endCDATA();
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.TEXT_NODE :
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //String data = ((Text) node).getData();
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nextIsRaw)
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextIsRaw = false;
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dispatachChars(node);
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dispatachChars(node);
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.ENTITY_REFERENCE_NODE :
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      EntityReference eref = (EntityReference) node;
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_contentHandler instanceof LexicalHandler)
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ((LexicalHandler) this.m_contentHandler).startEntity(
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          eref.getNodeName());
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // warning("Can not output entity to a pure SAX ContentHandler");
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * End processing of given node
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node Node we just finished processing
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws org.xml.sax.SAXException
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void endNode(Node node) throws org.xml.sax.SAXException
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (node.getNodeType())
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.DOCUMENT_NODE :
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.ELEMENT_NODE :
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String ns = m_dh.getNamespaceOfNode(node);
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(null == ns)
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ns = "";
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.m_contentHandler.endElement(ns,
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         m_dh.getLocalNameOfNode(node),
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         node.getNodeName());
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_Serializer == null) {
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Don't bother with endPrefixMapping calls if the ContentHandler is a
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // SerializationHandler because SerializationHandler's ignore the
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // endPrefixMapping() calls anyways. . . .  This is an optimization.
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Element elem_node = (Element) node;
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NamedNodeMap atts = elem_node.getAttributes();
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nAttrs = atts.getLength();
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // do the endPrefixMapping calls in reverse order
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // of the startPrefixMapping calls
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = (nAttrs-1); 0 <= i; i--)
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final Node attr = atts.item(i);
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String attrName = attr.getNodeName();
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int colon = attrName.indexOf(':');
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String prefix;
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:"))
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Use "" instead of null, as Xerces likes "" for the
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // name of the default namespace.  Fix attributed
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // to "Steven Murray" <smurray@ebt.com>.
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (colon < 0)
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = "";
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = attrName.substring(colon + 1);
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          this.m_contentHandler.endPrefixMapping(prefix);
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (colon > 0) {
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = attrName.substring(0, colon);
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.m_contentHandler.endPrefixMapping(prefix);
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          String uri = elem_node.getNamespaceURI();
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (uri != null) {
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              String prefix = elem_node.getPrefix();
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (prefix==null)
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                prefix="";
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              this.m_contentHandler.endPrefixMapping(prefix);
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.CDATA_SECTION_NODE :
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Node.ENTITY_REFERENCE_NODE :
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      EntityReference eref = (EntityReference) node;
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_contentHandler instanceof LexicalHandler)
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        LexicalHandler lh = ((LexicalHandler) this.m_contentHandler);
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        lh.endEntity(eref.getNodeName());
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}  //TreeWalker
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
528