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: DOM2Helper.java 468655 2006-10-28 07:12:06Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.utils;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.parsers.DocumentBuilder;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.parsers.DocumentBuilderFactory;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.parsers.ParserConfigurationException;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Attr;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Document;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Element;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.InputSource;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @deprecated Since the introduction of the DTM, this class will be removed.
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class provides a DOM level 2 "helper", which provides services currently
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not provided be the DOM standard.
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class DOM2Helper extends DOMHelper
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct an instance.
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DOM2Helper(){}
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Check node to see if it was created by a DOM implementation
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that this helper is intended to support. This is currently
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * disabled, and assumes all nodes are acceptable rather than checking
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that they implement org.apache.xerces.dom.NodeImpl.
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node The node to be tested.
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException if the node is not one which this
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * DOM2Helper can support. If we return without throwing the exception,
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the node is compatable.
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void checkNode(Node node) throws TransformerException
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // if(!(node instanceof org.apache.xerces.dom.NodeImpl))
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //  throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XERCES_CANNOT_HANDLE_NODES, new Object[]{((Object)node).getClass()})); //"DOM2Helper can not handle nodes of type"
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //+((Object)node).getClass());
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Returns true if the DOM implementation handled by this helper
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * supports the SAX ContentHandler interface.
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true (since Xerces does).
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean supportsSAX()
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Field m_doc: Document Node for the document this helper is currently
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * accessing or building
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #setDocument
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #getDocument
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  */
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Document m_doc;
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Specify which document this helper is currently operating on.
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param doc The DOM Document node for this document.
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #getDocument
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setDocument(Document doc)
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_doc = doc;
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Query which document this helper is currently operating on.
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The DOM Document node for this document.
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #setDocument
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Document getDocument()
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_doc;
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Parse an XML document.
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>Right now the Xerces DOMParser class is used.  This needs
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * fixing, either via jaxp, or via some other, standard method.</p>
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>The application can use this method to instruct the SAX parser
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to begin parsing an XML document from any valid input
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * source (a character stream, a byte stream, or a URI).</p>
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>Applications may not invoke this method while a parse is in
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * progress (they should create a new Parser instead for each
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * additional XML document).  Once a parse is complete, an
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * application may reuse the same Parser object, possibly with a
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * different input source.</p>
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param source The input source for the top-level of the
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        XML document.
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException if any checked exception is thrown.
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void parse(InputSource source) throws TransformerException
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // I guess I should use JAXP factory here... when it's legal.
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // org.apache.xerces.parsers.DOMParser parser
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //  = new org.apache.xerces.parsers.DOMParser();
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DocumentBuilderFactory builderFactory =
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DocumentBuilderFactory.newInstance();
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      builderFactory.setNamespaceAware(true);
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      builderFactory.setValidating(true);
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DocumentBuilder parser = builderFactory.newDocumentBuilder();
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      /*
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // domParser.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", getShouldExpandEntityRefs()? false : true);
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(m_useDOM2getNamespaceURI)
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      parser.setFeature("http://xml.org/sax/features/namespaces", true);
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      */
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      parser.setErrorHandler(
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        new org.apache.xml.utils.DefaultErrorHandler());
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if(null != m_entityResolver)
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // {
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // System.out.println("Setting the entity resolver.");
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //  parser.setEntityResolver(m_entityResolver);
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // }
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      setDocument(parser.parse(source));
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (org.xml.sax.SAXException se)
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new TransformerException(se);
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (ParserConfigurationException pce)
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new TransformerException(pce);
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (IOException ioe)
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new TransformerException(ioe);
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // setDocument(((org.apache.xerces.parsers.DOMParser)parser).getDocument());
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given an XML ID, return the element. This requires assistance from the
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * DOM and parser, and is meaningful only in the context of a DTD
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * or schema which declares attributes as being of type ID. This
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * information may or may not be available in all parsers, may or
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * may not be available for specific documents, and may or may not
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be available when validation is not turned on.
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param id The ID to search for, as a String.
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param doc The document to search within, as a DOM Document node.
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return DOM Element node with an attribute of type ID whose value
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * uniquely matches the requested id string, or null if there isn't
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * such an element or if the DOM can't answer the question for other
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * reasons.
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Element getElementByID(String id, Document doc)
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return doc.getElementById(id);
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Figure out whether node2 should be considered as being later
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in the document than node1, in Document Order as defined
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * by the XPath model. This may not agree with the ordering defined
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * by other XML applications.
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * There are some cases where ordering isn't defined, and neither are
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the results of this function -- though we'll generally return true.
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * TODO: Make sure this does the right thing with attribute nodes!!!
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node1 DOM Node to perform position comparison on.
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node2 DOM Node to perform position comparison on .
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return false if node2 comes before node1, otherwise return true.
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * You can think of this as
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isNodeAfter(Node node1, Node node2)
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Assume first that the nodes are DTM nodes, since discovering node
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // order is massivly faster for the DTM.
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(node1 instanceof DOMOrder && node2 instanceof DOMOrder)
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int index1 = ((DOMOrder) node1).getUid();
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int index2 = ((DOMOrder) node2).getUid();
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return index1 <= index2;
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // isNodeAfter will return true if node is after countedNode
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // in document order. The base isNodeAfter is sloooow (relatively).
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DOMHelper.isNodeAfter(node1, node2);
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the XPath-model parent of a node.  This version takes advantage
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of the DOM Level 2 Attr.ownerElement() method; the base version we
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * would otherwise inherit is prepared to fall back on exhaustively
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * walking the document to find an Attr's parent.
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node Node to be examined
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the DOM parent of the input node, if there is one, or the
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * ownerElement if the input node is an Attr, or null if the node is
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a Document, a DocumentFragment, or an orphan.
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static Node getParentOfNode(Node node)
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Node parent=node.getParentNode();
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(parent==null && (Node.ATTRIBUTE_NODE == node.getNodeType()) )
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           parent=((Attr) node).getOwnerElement();
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return parent;
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Returns the local name of the given node, as defined by the
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * XML Namespaces specification. This is prepared to handle documents
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * built using DOM Level 1 methods by falling back upon explicitly
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * parsing the node name.
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n Node to be examined
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String containing the local name, or null if the node
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * was not assigned a Namespace.
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getLocalNameOfNode(Node n)
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String name = n.getLocalName();
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (null == name) ? super.getLocalNameOfNode(n) : name;
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Returns the Namespace Name (Namespace URI) for the given node.
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * In a Level 2 DOM, you can ask the node itself. Note, however, that
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * doing so conflicts with our decision in getLocalNameOfNode not
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to trust the that the DOM was indeed created using the Level 2
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * methods. If Level 1 methods were used, these two functions will
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * disagree with each other.
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * TODO: Reconcile with getLocalNameOfNode.
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n Node to be examined
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String containing the Namespace URI bound to this DOM node
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * at the time the Node was created.
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getNamespaceOfNode(Node n)
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return n.getNamespaceURI();
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Field m_useDOM2getNamespaceURI is a compile-time flag which
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  gates some of the parser options used to build a DOM -- but
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that code is commented out at this time and nobody else
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * references it, so I've commented this out as well. */
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //private boolean m_useDOM2getNamespaceURI = false;
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
315