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: DOM2DTM.java 478671 2006-11-23 21:00:31Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.dtm.ref.dom2dtm; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.SourceLocator; 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.dom.DOMSource; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMManager; 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMWSFilter; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.DTMDefaultBaseIterators; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.DTMManagerDefault; 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.ExpandedNameTable; 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.IncrementalSAXSource; 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources; 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages; 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.FastStringBuffer; 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.QName; 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.StringBufferPool; 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.TreeWalker; 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLCharacterRecognizer; 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLString; 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLStringFactory; 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Attr; 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Document; 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.DocumentType; 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Element; 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Entity; 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.NamedNodeMap; 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node; 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ContentHandler; 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** The <code>DOM2DTM</code> class serves up a DOM's contents via the 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DTM API. 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Note that it doesn't necessarily represent a full Document 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * tree. You can wrap a DOM2DTM around a specific node and its subtree 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and the right things should happen. (I don't _think_ we currently 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * support DocumentFrgment nodes as roots, though that might be worth 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * considering.) 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Note too that we do not currently attempt to track document 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * mutation. If you alter the DOM after wrapping DOM2DTM around it, 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * all bets are off. 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class DOM2DTM extends DTMDefaultBaseIterators 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final boolean JJK_DEBUG=false; 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final boolean JJK_NEWCODE=true; 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Manefest constant 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final String NAMESPACE_DECL_NS="http://www.w3.org/XML/1998/namespace"; 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** The current position in the DOM tree. Last node examined for 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * possible copying to DTM. */ 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson transient private Node m_pos; 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** The current position in the DTM tree. Who children get appended to. */ 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int m_last_parent=0; 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** The current position in the DTM tree. Who children reference as their 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * previous sib. */ 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int m_last_kid=NULL; 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** The top of the subtree. 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW%: 'may not be the same as m_context if "//foo" pattern.' 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson transient private Node m_root; 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** True iff the first element has been processed. This is used to control 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson synthesis of the implied xml: namespace declaration node. */ 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean m_processedFirstElement=false; 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** true if ALL the nodes in the m_root subtree have been processed; 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * false if our incremental build has not yet finished scanning the 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DOM tree. */ 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson transient private boolean m_nodesAreProcessed; 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** The node objects. The instance part of the handle indexes 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * directly into this vector. Each DTM node may actually be 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * composed of several DOM nodes (for example, if logically-adjacent 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Text/CDATASection nodes in the DOM have been coalesced into a 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * single DTM Text node); this table points only to the first in 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * that sequence. */ 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected Vector m_nodes = new Vector(); 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Construct a DOM2DTM object from a DOM node. 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param mgr The DTMManager who owns this DTM. 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param domSource the DOM source that this DTM will wrap. 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param dtmIdentity The DTM identity ID for this DTM. 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param whiteSpaceFilter The white space filter for this DTM, which may 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * be null. 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xstringfactory XMLString factory for creating character content. 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param doIndexing true if the caller considers it worth it to use 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * indexing schemes. 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public DOM2DTM(DTMManager mgr, DOMSource domSource, 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int dtmIdentity, DTMWSFilter whiteSpaceFilter, 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XMLStringFactory xstringfactory, 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean doIndexing) 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson super(mgr, domSource, dtmIdentity, whiteSpaceFilter, 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xstringfactory, doIndexing); 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Initialize DOM navigation 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_pos=m_root = domSource.getNode(); 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Initialize DTM navigation 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_parent=m_last_kid=NULL; 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_kid=addNode(m_root, m_last_parent,m_last_kid, NULL); 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Apparently the domSource root may not actually be the 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Document node. If it's an Element node, we need to immediately 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // add its attributes. Adapted from nextNode(). 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Move this logic into addNode and recurse? Cleaner! 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (If it's an EntityReference node, we're probably in 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // seriously bad trouble. For now 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // I'm just hoping nobody is ever quite that foolish... %REVIEW%) 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %ISSUE% What about inherited namespaces in this case? 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Do we need to special-case initialize them into the DTM model? 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(ELEMENT_NODE == m_root.getNodeType()) 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson NamedNodeMap attrs=m_root.getAttributes(); 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int attrsize=(attrs==null) ? 0 : attrs.getLength(); 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(attrsize>0) 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int attrIndex=NULL; // start with no previous sib 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(int i=0;i<attrsize;++i) 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No need to force nodetype in this case; 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // addNode() will take care of switching it from 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Attr to Namespace if necessary. 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrIndex=addNode(attrs.item(i),0,attrIndex,NULL); 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(DTM.NULL,attrIndex); 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Terminate list of attrs, and make sure they aren't 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // considered children of the element 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(DTM.NULL,attrIndex); 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // IMPORTANT: This does NOT change m_last_parent or m_last_kid! 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // if attrs exist 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } //if(ELEMENT_NODE) 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Initialize DTM-completed status 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nodesAreProcessed = false; 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Construct the node map from the node. 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node The node that is to be added to the DTM. 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param parentIndex The current parent index. 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param previousSibling The previous sibling index. 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param forceNodeType If not DTM.NULL, overrides the DOM node type. 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Used to force nodes to Text rather than CDATASection when their 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * coalesced value includes ordinary Text nodes (current DTM behavior). 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The index identity of the node that was added. 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected int addNode(Node node, int parentIndex, 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int previousSibling, int forceNodeType) 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nodeIndex = m_nodes.size(); 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Have we overflowed a DTM Identity's addressing range? 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS)) 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_mgr==null) 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ClassCastException(); 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Handle as Extended Addressing 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr; 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int id=mgrD.getFirstFreeDTMID(); 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson mgrD.addDTM(this,id,nodeIndex); 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS); 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(ClassCastException e) 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Wrong error message, but I've been told we're trying 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // not to add messages right not for I18N reasons. 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Should this be a Fatal Error? 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null));//"No more DTM IDs are available"; 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_size++; 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ensureSize(nodeIndex); 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type; 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(NULL==forceNodeType) 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type = node.getNodeType(); 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type=forceNodeType; 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% The Namespace Spec currently says that Namespaces are 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // processed in a non-namespace-aware manner, by matching the 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // QName, even though there is in fact a namespace assigned to 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // these nodes in the DOM. If and when that changes, we will have 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to consider whether we check the namespace-for-namespaces 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // rather than the node name. 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% Note that the DOM does not necessarily explicitly declare 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // all the namespaces it uses. DOM Level 3 will introduce a 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // namespace-normalization operation which reconciles that, and we 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // can request that users invoke it or otherwise ensure that the 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // tree is namespace-well-formed before passing the DOM to Xalan. 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // But if they don't, what should we do about it? We probably 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // don't want to alter the source DOM (and may not be able to do 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // so if it's read-only). The best available answer might be to 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // synthesize additional DTM Namespace Nodes that don't correspond 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to DOM Attr Nodes. 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (Node.ATTRIBUTE_NODE == type) 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String name = node.getNodeName(); 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (name.startsWith("xmlns:") || name.equals("xmlns")) 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type = DTM.NAMESPACE_NODE; 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nodes.addElement(node); 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(NOTPROCESSED,nodeIndex); 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(NOTPROCESSED,nodeIndex); 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_prevsib.setElementAt(previousSibling,nodeIndex); 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_parent.setElementAt(parentIndex,nodeIndex); 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DTM.NULL != parentIndex && 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type != DTM.ATTRIBUTE_NODE && 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type != DTM.NAMESPACE_NODE) 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If the DTM parent had no children, this becomes its first child. 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(NOTPROCESSED == m_firstch.elementAt(parentIndex)) 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(nodeIndex,parentIndex); 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String nsURI = node.getNamespaceURI(); 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Deal with the difference between Namespace spec and XSLT 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // definitions of local name. (The former says PIs don't have 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // localnames; the latter says they do.) 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String localName = (type == Node.PROCESSING_INSTRUCTION_NODE) ? 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson node.getNodeName() : 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson node.getLocalName(); 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Hack to make DOM1 sort of work... 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(((type == Node.ELEMENT_NODE) || (type == Node.ATTRIBUTE_NODE)) 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson && null == localName) 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson localName = node.getNodeName(); // -sb 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ExpandedNameTable exnt = m_expandedNameTable; 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% Nodes created with the old non-namespace-aware DOM 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // calls createElement() and createAttribute() will never have a 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // localname. That will cause their expandedNameID to be just the 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // nodeType... which will keep them from being matched 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // successfully by name. Since the DOM makes no promise that 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // those will participate in namespace processing, this is 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // officially accepted as Not Our Fault. But it might be nice to 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // issue a diagnostic message! 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(node.getLocalName()==null && 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (type==Node.ELEMENT_NODE || type==Node.ATTRIBUTE_NODE)) 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // warning("DOM 'level 1' node "+node.getNodeName()+" won't be mapped properly in DOM2DTM."); 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int expandedNameID = (null != localName) 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ? exnt.getExpandedTypeID(nsURI, localName, type) : 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson exnt.getExpandedTypeID(type); 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_exptype.setElementAt(expandedNameID,nodeIndex); 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson indexNode(expandedNameID, nodeIndex); 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (DTM.NULL != previousSibling) 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(nodeIndex,previousSibling); 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This should be done after m_exptype has been set, and probably should 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // always be the last thing we do 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (type == DTM.NAMESPACE_NODE) 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson declareNamespaceInContext(parentIndex,nodeIndex); 3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return nodeIndex; 3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the number of nodes that have been added. 3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getNumberOfNodes() 3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return m_nodes.size(); 3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This method iterates to the next node that will be added to the table. 3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Each call to this method adds a new node to the table, unless the end 3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is reached, in which case it returns null. 3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The true if a next node is found or false if 3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * there are no more nodes. 3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected boolean nextNode() 3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Non-recursive one-fetch-at-a-time depth-first traversal with 3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // attribute/namespace nodes and white-space stripping. 3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Navigating the DOM is simple, navigating the DTM is simple; 3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // keeping track of both at once is a trifle baroque but at least 3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we've avoided most of the special cases. 3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (m_nodesAreProcessed) 3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Is this local copy Really Useful from a performance 3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // point of view? Or is this a false microoptimization? 3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node pos=m_pos; 3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node next=null; 3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nexttype=NULL; 3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Navigate DOM tree 3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson do 3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Look down to first child. 3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (pos.hasChildNodes()) 3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next = pos.getFirstChild(); 3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% There's probably a more elegant way to skip 3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the doctype. (Just let it go and Suppress it? 3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(next!=null && DOCUMENT_TYPE_NODE==next.getNodeType()) 3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next=next.getNextSibling(); 3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Push DTM context -- except for children of Entity References, 3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // which have no DTM equivalent and cause no DTM navigation. 3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(ENTITY_REFERENCE_NODE!=pos.getNodeType()) 3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_parent=m_last_kid; 3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_kid=NULL; 3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Whitespace-handler context stacking 3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null != m_wsfilter) 3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson short wsv = 3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_wsfilter.getShouldStripSpace(makeNodeHandle(m_last_parent),this); 3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) 3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ? getShouldStripWhitespace() 3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson : (DTMWSFilter.STRIP == wsv); 3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson pushShouldStripWhitespace(shouldStrip); 3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // if(m_wsfilter) 3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If that fails, look up and right (but not past root!) 3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_last_kid!=NULL) 3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Last node posted at this level had no more children 3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If it has _no_ children, we need to record that. 3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_firstch.elementAt(m_last_kid)==NOTPROCESSED) 3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(NULL,m_last_kid); 3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(m_last_parent != NULL) 3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% There's probably a more elegant way to 3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // skip the doctype. (Just let it go and Suppress it? 3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next = pos.getNextSibling(); 3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(next!=null && DOCUMENT_TYPE_NODE==next.getNodeType()) 3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next=next.getNextSibling(); 3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(next!=null) 3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; // Found it! 3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No next-sibling found. Pop the DOM. 3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson pos=pos.getParentNode(); 3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(pos==null) 4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% Should never arise, but I want to be sure of that... 4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(JJK_DEBUG) 4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("***** DOM2DTM Pop Control Flow problem"); 4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(;;); // Freeze right here! 4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // The only parents in the DTM are Elements. However, 4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the DOM could contain EntityReferences. If we 4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // encounter one, pop it _without_ popping DTM. 4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(pos!=null && ENTITY_REFERENCE_NODE == pos.getNodeType()) 4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Nothing needs doing 4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(JJK_DEBUG) 4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("***** DOM2DTM popping EntRef"); 4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson popShouldStripWhitespace(); 4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Fix and pop DTM 4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_last_kid==NULL) 4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(NULL,m_last_parent); // Popping from an element 4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(NULL,m_last_kid); // Popping from anything else 4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_parent=m_parent.elementAt(m_last_kid=m_last_parent); 4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(m_last_parent==NULL) 4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next=null; 4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(next!=null) 4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nexttype=next.getNodeType(); 4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If it's an entity ref, advance past it. 4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Should we let this out the door and just suppress it? 4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // More work, but simpler code, more likely to be correct, and 4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // it doesn't happen very often. We'd get rid of the loop too. 4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (ENTITY_REFERENCE_NODE == nexttype) 4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson pos=next; 4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (ENTITY_REFERENCE_NODE == nexttype); 4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Did we run out of the tree? 4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(next==null) 4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(NULL,0); 4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nodesAreProcessed = true; 4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_pos=null; 4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(JJK_DEBUG) 4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("***** DOM2DTM Crosscheck:"); 4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(int i=0;i<m_nodes.size();++i) 4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println(i+":\t"+m_firstch.elementAt(i)+"\t"+m_nextsib.elementAt(i)); 4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Text needs some special handling: 4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // DTM may skip whitespace. This is handled by the suppressNode flag, which 4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // when true will keep the DTM node from being created. 4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // DTM only directly records the first DOM node of any logically-contiguous 4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // sequence. The lastTextNode value will be set to the last node in the 4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // contiguous sequence, and -- AFTER the DTM addNode -- can be used to 4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // advance next over this whole block. Should be simpler than special-casing 4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the above loop for "Was the logically-preceeding sibling a text node". 4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Finally, a DTM node should be considered a CDATASection only if all the 4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // contiguous text it covers is CDATASections. The first Text should 4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // force DTM to Text. 4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean suppressNode=false; 4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node lastTextNode=null; 4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nexttype=next.getNodeType(); 4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // nexttype=pos.getNodeType(); 4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE == nexttype || CDATA_SECTION_NODE == nexttype) 4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If filtering, initially assume we're going to suppress the node 4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson suppressNode=((null != m_wsfilter) && getShouldStripWhitespace()); 4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Scan logically contiguous text (siblings, plus "flattening" 4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // of entity reference boundaries). 4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node n=next; 4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(n!=null) 4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson lastTextNode=n; 4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Any Text node means DTM considers it all Text 4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE == n.getNodeType()) 4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nexttype=TEXT_NODE; 4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Any non-whitespace in this sequence blocks whitespace 4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // suppression 5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson suppressNode &= 5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XMLCharacterRecognizer.isWhiteSpace(n.getNodeValue()); 5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=logicalNextDOMTextNode(n); 5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Special handling for PIs: Some DOMs represent the XML 5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Declaration as a PI. This is officially incorrect, per the DOM 5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // spec, but is considered a "wrong but tolerable" temporary 5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // workaround pending proper handling of these fields in DOM Level 5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3. We want to recognize and reject that case. 5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if(PROCESSING_INSTRUCTION_NODE==nexttype) 5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson suppressNode = (pos.getNodeName().toLowerCase().equals("xml")); 5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(!suppressNode) 5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Inserting next. NOTE that we force the node type; for 5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // coalesced Text, this records CDATASections adjacent to 5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ordinary Text as Text. 5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nextindex=addNode(next,m_last_parent,m_last_kid, 5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nexttype); 5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_last_kid=nextindex; 5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(ELEMENT_NODE == nexttype) 5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int attrIndex=NULL; // start with no previous sib 5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Process attributes _now_, rather than waiting. 5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Simpler control flow, makes NS cache available immediately. 5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson NamedNodeMap attrs=next.getAttributes(); 5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int attrsize=(attrs==null) ? 0 : attrs.getLength(); 5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(attrsize>0) 5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(int i=0;i<attrsize;++i) 5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No need to force nodetype in this case; 5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // addNode() will take care of switching it from 5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Attr to Namespace if necessary. 5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrIndex=addNode(attrs.item(i), 5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nextindex,attrIndex,NULL); 5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(DTM.NULL,attrIndex); 5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If the xml: prefix is explicitly declared 5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we don't need to synthesize one. 5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // NOTE that XML Namespaces were not originally 5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // defined as being namespace-aware (grrr), and 5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // while the W3C is planning to fix this it's 5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // safer for now to test the QName and trust the 5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // parsers to prevent anyone from redefining the 5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // reserved xmlns: prefix 5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(!m_processedFirstElement 5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson && "xmlns:xml".equals(attrs.item(i).getNodeName())) 5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_processedFirstElement=true; 5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Terminate list of attrs, and make sure they aren't 5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // considered children of the element 5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // if attrs exist 5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(!m_processedFirstElement) 5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // The DOM might not have an explicit declaration for the 5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // implicit "xml:" prefix, but the XPath data model 5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // requires that this appear as a Namespace Node so we 5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // have to synthesize one. You can think of this as 5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // being a default attribute defined by the XML 5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Namespaces spec rather than by the DTD. 5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrIndex=addNode(new DOM2DTMdefaultNamespaceDeclarationNode( 5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (Element)next,"xml",NAMESPACE_DECL_NS, 5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson makeNodeHandle(((attrIndex==NULL)?nextindex:attrIndex)+1) 5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ), 5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nextindex,attrIndex,NULL); 5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_firstch.setElementAt(DTM.NULL,attrIndex); 5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_processedFirstElement=true; 5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(attrIndex!=NULL) 5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_nextsib.setElementAt(DTM.NULL,attrIndex); 5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } //if(ELEMENT_NODE) 5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // (if !suppressNode) 5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Text postprocessing: Act on values stored above 5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE == nexttype || CDATA_SECTION_NODE == nexttype) 5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% If nexttype was forced to TEXT, patch the DTM node 5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson next=lastTextNode; // Advance the DOM cursor over contiguous text 5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Remember where we left off. 5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_pos=next; 5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return true; 5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return an DOM node for the given node. 5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node ID. 6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return A node representation of the DTM node. 6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public Node getNode(int nodeHandle) 6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int identity = makeNodeIdentity(nodeHandle); 6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (Node) m_nodes.elementAt(identity); 6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a Node from an identity index. 6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * NEEDSDOC @param nodeIdentity 6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * NEEDSDOC ($objectName$) @return 6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected Node lookupNode(int nodeIdentity) 6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (Node) m_nodes.elementAt(nodeIdentity); 6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the next node identity value in the list, and call the iterator 6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * if it hasn't been added yet. 6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param identity The node identity (index). 6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return identity+1, or DTM.NULL. 6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected int getNextNodeIdentity(int identity) 6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson identity += 1; 6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (identity >= m_nodes.size()) 6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (!nextNode()) 6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson identity = DTM.NULL; 6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return identity; 6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the handle from a Node. 6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%OPT% This will be pretty slow.</p> 6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%OPT% An XPath-like search (walk up DOM to root, tracking path; 6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * walk down DTM reconstructing path) might be considerably faster 6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * on later nodes in large documents. That might also imply improving 6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * this call to handle nodes which would be in this DTM but 6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * have not yet been built, which might or might not be a Good Thing.</p> 6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% This relies on being able to test node-identity via 6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * object-identity. DTM2DOM proxying is a great example of a case where 6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * that doesn't work. DOM Level 3 will provide the isSameNode() method 6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to fix that, but until then this is going to be flaky. 6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node A node, which may be null. 6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The node handle or <code>DTM.NULL</code>. 6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int getHandleFromNode(Node node) 6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != node) 6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int len = m_nodes.size(); 6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean isMore; 6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int i = 0; 6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson do 6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (; i < len; i++) 6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (m_nodes.elementAt(i) == node) 6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return makeNodeHandle(i); 6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson isMore = nextNode(); 6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson len = m_nodes.size(); 6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(isMore || i < len); 6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return DTM.NULL; 6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Get the handle from a Node. This is a more robust version of 6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * getHandleFromNode, intended to be usable by the public. 6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%OPT% This will be pretty slow.</p> 6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% This relies on being able to test node-identity via 6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * object-identity. DTM2DOM proxying is a great example of a case where 6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * that doesn't work. DOM Level 3 will provide the isSameNode() method 6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to fix that, but until then this is going to be flaky. 6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node A node, which may be null. 7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The node handle or <code>DTM.NULL</code>. */ 7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getHandleOfNode(Node node) 7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != node) 7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Is Node actually within the same document? If not, don't search! 7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This would be easier if m_root was always the Document node, but 7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we decided to allow wrapping a DTM around a subtree. 7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if((m_root==node) || 7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (m_root.getNodeType()==DOCUMENT_NODE && 7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_root==node.getOwnerDocument()) || 7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (m_root.getNodeType()!=DOCUMENT_NODE && 7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_root.getOwnerDocument()==node.getOwnerDocument()) 7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ) 7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If node _is_ in m_root's tree, find its handle 7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %OPT% This check may be improved significantly when DOM 7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Level 3 nodeKey and relative-order tests become 7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // available! 7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(Node cursor=node; 7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson cursor!=null; 7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson cursor= 7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (cursor.getNodeType()!=ATTRIBUTE_NODE) 7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ? cursor.getParentNode() 7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson : ((org.w3c.dom.Attr)cursor).getOwnerElement()) 7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(cursor==m_root) 7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // We know this node; find its handle. 7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getHandleFromNode(node); 7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // for ancestors of node 7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // if node and m_root in same Document 7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // if node!=null 7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return DTM.NULL; 7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Retrieves an attribute node by by qualified name and namespace URI. 7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle int Handle of the node upon which to look up this attribute.. 7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param namespaceURI The namespace URI of the attribute to 7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * retrieve, or null. 7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param name The local name of the attribute to 7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * retrieve. 7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The attribute node handle with the specified name ( 7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such 7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * attribute. 7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getAttributeNode(int nodeHandle, String namespaceURI, 7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String name) 7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %OPT% This is probably slower than it needs to be. 7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == namespaceURI) 7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson namespaceURI = ""; 7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = getNodeType(nodeHandle); 7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (DTM.ELEMENT_NODE == type) 7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assume that attributes immediately follow the element. 7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int identity = makeNodeIdentity(nodeHandle); 7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (DTM.NULL != (identity = getNextNodeIdentity(identity))) 7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assume this can not be null. 7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type = _type(identity); 7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% 7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Should namespace nodes be retrievable DOM-style as attrs? 7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If not we need a separate function... which may be desirable 7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // architecturally, but which is ugly from a code point of view. 7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (If we REALLY insist on it, this code should become a subroutine 7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // of both -- retrieve the node, then test if the type matches 7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // what you're looking for.) 7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (type == DTM.ATTRIBUTE_NODE || type==DTM.NAMESPACE_NODE) 7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = lookupNode(identity); 7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String nodeuri = node.getNamespaceURI(); 7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == nodeuri) 7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nodeuri = ""; 7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String nodelocalname = node.getLocalName(); 7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (nodeuri.equals(namespaceURI) && name.equals(nodelocalname)) 7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return makeNodeHandle(identity); 7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else // if (DTM.NAMESPACE_NODE != type) 7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return DTM.NULL; 8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the string-value of a node as a String object 8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * (see http://www.w3.org/TR/xpath#data-model 8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for the definition of a node's string-value). 8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node ID. 8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return A string object that represents the string-value of the given node. 8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XMLString getStringValue(int nodeHandle) 8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = getNodeType(nodeHandle); 8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% If an element only has one text node, we should just use it 8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // directly. 8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DTM.ELEMENT_NODE == type || DTM.DOCUMENT_NODE == type 8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || DTM.DOCUMENT_FRAGMENT_NODE == type) 8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FastStringBuffer buf = StringBufferPool.get(); 8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String s; 8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson getNodeData(node, buf); 8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson s = (buf.length() > 0) ? buf.toString() : ""; 8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson finally 8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StringBufferPool.free(buf); 8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return m_xstrf.newstr( s ); 8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if(TEXT_NODE == type || CDATA_SECTION_NODE == type) 8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If this is a DTM text node, it may be made of multiple DOM text 8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // nodes -- including navigating into Entity References. DOM2DTM 8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // records the first node in the sequence and requires that we 8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // pick up the others when we retrieve the DTM node's value. 8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% DOM Level 3 is expected to add a "whole text" 8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // retrieval method which performs this function for us. 8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FastStringBuffer buf = StringBufferPool.get(); 8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(node!=null) 8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson buf.append(node.getNodeValue()); 8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson node=logicalNextDOMTextNode(node); 8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String s=(buf.length() > 0) ? buf.toString() : ""; 8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StringBufferPool.free(buf); 8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return m_xstrf.newstr( s ); 8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return m_xstrf.newstr( node.getNodeValue() ); 8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Determine if the string-value of a node is whitespace 8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node Handle. 8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Return true if the given node is whitespace. 8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public boolean isWhitespace(int nodeHandle) 8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = getNodeType(nodeHandle); 8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE == type || CDATA_SECTION_NODE == type) 8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If this is a DTM text node, it may be made of multiple DOM text 8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // nodes -- including navigating into Entity References. DOM2DTM 8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // records the first node in the sequence and requires that we 8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // pick up the others when we retrieve the DTM node's value. 8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% DOM Level 3 is expected to add a "whole text" 8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // retrieval method which performs this function for us. 8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FastStringBuffer buf = StringBufferPool.get(); 8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(node!=null) 8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson buf.append(node.getNodeValue()); 8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson node=logicalNextDOMTextNode(node); 8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean b = buf.isWhitespace(0, buf.length()); 8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StringBufferPool.free(buf); 8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return b; 8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Retrieve the text content of a DOM subtree, appending it into a 8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * user-supplied FastStringBuffer object. Note that attributes are 8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not considered part of the content of an element. 8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * There are open questions regarding whitespace stripping. 9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Currently we make no special effort in that regard, since the standard 9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DOM doesn't yet provide DTD-based information to distinguish 9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * whitespace-in-element-context from genuine #PCDATA. Note that we 9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * should probably also consider xml:space if/when we address this. 9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DOM Level 3 may solve the problem for us. 9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% Actually, since this method operates on the DOM side of the 9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * fence rather than the DTM side, it SHOULDN'T do 9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * any special handling. The DOM does what the DOM does; if you want 9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DTM-level abstractions, use DTM-level methods. 9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node Node whose subtree is to be walked, gathering the 9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * contents of all Text or CDATASection nodes. 9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param buf FastStringBuffer into which the contents of the text 9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * nodes are to be concatenated. 9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected static void getNodeData(Node node, FastStringBuffer buf) 9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (node.getNodeType()) 9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.DOCUMENT_FRAGMENT_NODE : 9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.DOCUMENT_NODE : 9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.ELEMENT_NODE : 9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (Node child = node.getFirstChild(); null != child; 9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson child = child.getNextSibling()) 9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson getNodeData(child, buf); 9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.TEXT_NODE : 9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.CDATA_SECTION_NODE : 9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.ATTRIBUTE_NODE : // Never a child but might be our starting node 9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson buf.append(node.getNodeValue()); 9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.PROCESSING_INSTRUCTION_NODE : 9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING); 9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ignore 9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return its DOM-style node name. This will 9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * include names such as #text or #document. 9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle the id of the node. 9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String Name of this node, which may be an empty string. 9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% Document when empty string is possible... 9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW-COMMENT% It should never be empty, should it? 9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getNodeName(int nodeHandle) 9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assume non-null. 9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return node.getNodeName(); 9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return the XPath node name. This should be 9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the name as described by the XPath data model, NOT the DOM-style 9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * name. 9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle the id of the node. 9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String Name of this node, which may be an empty string. 9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getNodeNameX(int nodeHandle) 9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String name; 9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson short type = getNodeType(nodeHandle); 9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (type) 9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.NAMESPACE_NODE : 9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = node.getNodeName(); 9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(name.startsWith("xmlns:")) 9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = QName.getLocalPart(name); 9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if(name.equals("xmlns")) 9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = ""; 9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ATTRIBUTE_NODE : 9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ELEMENT_NODE : 9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ENTITY_REFERENCE_NODE : 9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.PROCESSING_INSTRUCTION_NODE : 10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = node.getNodeName(); 10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = ""; 10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return name; 10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return its XPath-style localname. 10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * (As defined in Namespaces, this is the portion of the name after any 10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * colon character). 10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle the id of the node. 10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String Local name of this node. 10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getLocalName(int nodeHandle) 10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(JJK_NEWCODE) 10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int id=makeNodeIdentity(nodeHandle); 10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(NULL==id) return null; 10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node newnode=(Node)m_nodes.elementAt(id); 10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String newname=newnode.getLocalName(); 10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == newname) 10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XSLT treats PIs, and possibly other things, as having QNames. 10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String qname = newnode.getNodeName(); 10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if('#'==qname.charAt(0)) 10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Match old default for this function 10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This conversion may or may not be necessary 10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson newname=""; 10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int index = qname.indexOf(':'); 10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson newname = (index < 0) ? qname : qname.substring(index + 1); 10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return newname; 10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String name; 10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson short type = getNodeType(nodeHandle); 10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (type) 10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ATTRIBUTE_NODE : 10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ELEMENT_NODE : 10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ENTITY_REFERENCE_NODE : 10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.NAMESPACE_NODE : 10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.PROCESSING_INSTRUCTION_NODE : 10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = node.getLocalName(); 10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == name) 10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String qname = node.getNodeName(); 10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int index = qname.indexOf(':'); 10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = (index < 0) ? qname : qname.substring(index + 1); 10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson name = ""; 10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return name; 10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a namespace handle, return the prefix that the namespace decl is 10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * mapping. 10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return the prefix used to map to the namespace. 10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> %REVIEW% Are you sure you want "" for no prefix? </p> 10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb </p> 10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle the id of the node. 10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String prefix of this node's name, or "" if no explicit 10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * namespace prefix was given. 10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getPrefix(int nodeHandle) 10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String prefix; 10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson short type = getNodeType(nodeHandle); 10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (type) 11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.NAMESPACE_NODE : 11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String qname = node.getNodeName(); 11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int index = qname.indexOf(':'); 11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefix = (index < 0) ? "" : qname.substring(index + 1); 11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ATTRIBUTE_NODE : 11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ELEMENT_NODE : 11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String qname = node.getNodeName(); 11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int index = qname.indexOf(':'); 11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefix = (index < 0) ? "" : qname.substring(0, index); 11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefix = ""; 11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return prefix; 11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return its DOM-style namespace URI 11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * (As defined in Namespaces, this is the declared URI which this node's 11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * prefix -- or default in lieu thereof -- was mapped to.) 11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%REVIEW% Null or ""? -sb</p> 11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle the id of the node. 11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String URI value of this node's namespace, or null if no 11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * namespace was resolved. 11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getNamespaceURI(int nodeHandle) 11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(JJK_NEWCODE) 11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int id=makeNodeIdentity(nodeHandle); 11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(id==NULL) return null; 11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node=(Node)m_nodes.elementAt(id); 11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return node.getNamespaceURI(); 11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String nsuri; 11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson short type = getNodeType(nodeHandle); 11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (type) 11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ATTRIBUTE_NODE : 11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ELEMENT_NODE : 11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.ENTITY_REFERENCE_NODE : 11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.NAMESPACE_NODE : 11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case DTM.PROCESSING_INSTRUCTION_NODE : 11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assume not null. 11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nsuri = node.getNamespaceURI(); 11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %TBD% Handle DOM1? 11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nsuri = null; 11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return nsuri; 11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Utility function: Given a DOM Text node, determine whether it is 11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * logically followed by another Text or CDATASection node. This may 11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * involve traversing into Entity References. 11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% DOM Level 3 is expected to add functionality which may 11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * allow us to retire this. 11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private Node logicalNextDOMTextNode(Node n) 11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node p=n.getNextSibling(); 11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(p==null) 11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Walk out of any EntityReferenceNodes that ended with text 11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(n=n.getParentNode(); 11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n!=null && ENTITY_REFERENCE_NODE == n.getNodeType(); 11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=n.getParentNode()) 11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson p=n.getNextSibling(); 11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(p!=null) 12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=p; 12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(n!=null && ENTITY_REFERENCE_NODE == n.getNodeType()) 12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Walk into any EntityReferenceNodes that start with text 12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(n.hasChildNodes()) 12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=n.getFirstChild(); 12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=n.getNextSibling(); 12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(n!=null) 12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Found a logical next sibling. Is it text? 12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int ntype=n.getNodeType(); 12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE != ntype && CDATA_SECTION_NODE != ntype) 12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=null; 12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return n; 12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Given a node handle, return its node value. This is mostly 12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * as defined by the DOM, but may ignore some conveniences. 12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node id. 12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String Value of this node, or null if not 12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * meaningful for this node type. 12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getNodeValue(int nodeHandle) 12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // The _type(nodeHandle) call was taking the lion's share of our 12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // time, and was wrong anyway since it wasn't coverting handle to 12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // identity. Inlined it. 12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = _exptype(makeNodeIdentity(nodeHandle)); 12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson type=(NULL != type) ? getNodeType(nodeHandle) : NULL; 12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE!=type && CDATA_SECTION_NODE!=type) 12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getNode(nodeHandle).getNodeValue(); 12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If this is a DTM text node, it may be made of multiple DOM text 12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // nodes -- including navigating into Entity References. DOM2DTM 12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // records the first node in the sequence and requires that we 12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // pick up the others when we retrieve the DTM node's value. 12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% DOM Level 3 is expected to add a "whole text" 12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // retrieval method which performs this function for us. 12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node n=logicalNextDOMTextNode(node); 12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(n==null) 12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return node.getNodeValue(); 12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FastStringBuffer buf = StringBufferPool.get(); 12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson buf.append(node.getNodeValue()); 12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(n!=null) 12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson buf.append(n.getNodeValue()); 12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson n=logicalNextDOMTextNode(n); 12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String s = (buf.length() > 0) ? buf.toString() : ""; 12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StringBufferPool.free(buf); 12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return s; 12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * A document type declaration information item has the following properties: 12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1. [system identifier] The system identifier of the external subset, if 12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * it exists. Otherwise this property has no value. 12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return the system identifier String object, or null if there is none. 12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getDocumentTypeDeclarationSystemIdentifier() 12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Document doc; 12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (m_root.getNodeType() == Node.DOCUMENT_NODE) 12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson doc = (Document) m_root; 12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson doc = m_root.getOwnerDocument(); 12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != doc) 12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DocumentType dtd = doc.getDoctype(); 12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != dtd) 12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return dtd.getSystemId(); 12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return the public identifier of the external subset, 12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * normalized as described in 4.2.2 External Entities [XML]. If there is 13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * no external subset or if it has no public identifier, this property 13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * has no value. 13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return the public identifier String object, or null if there is none. 13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getDocumentTypeDeclarationPublicIdentifier() 13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Document doc; 13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (m_root.getNodeType() == Node.DOCUMENT_NODE) 13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson doc = (Document) m_root; 13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson doc = m_root.getOwnerDocument(); 13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != doc) 13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DocumentType dtd = doc.getDoctype(); 13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != dtd) 13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return dtd.getPublicId(); 13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Returns the <code>Element</code> whose <code>ID</code> is given by 13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>elementId</code>. If no such element exists, returns 13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>DTM.NULL</code>. Behavior is not defined if more than one element 13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * has this <code>ID</code>. Attributes (including those 13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * with the name "ID") are not of type ID unless so defined by DTD/Schema 13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * information available to the DTM implementation. 13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Implementations that do not know whether attributes are of type ID or 13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not are expected to return <code>DTM.NULL</code>. 13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%REVIEW% Presumably IDs are still scoped to a single document, 13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and this operation searches only within a single document, right? 13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Wouldn't want collisions between DTMs in the same process.</p> 13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param elementId The unique <code>id</code> value for an element. 13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The handle of the matching element. 13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getElementById(String elementId) 13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) 13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ? (Document) m_root : m_root.getOwnerDocument(); 13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null != doc) 13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node elem = doc.getElementById(elementId); 13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null != elem) 13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int elemHandle = getHandleFromNode(elem); 13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DTM.NULL == elemHandle) 13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int identity = m_nodes.size()-1; 13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (DTM.NULL != (identity = getNextNodeIdentity(identity))) 13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(identity); 13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(node == elem) 13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson elemHandle = getHandleFromNode(elem); 13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return elemHandle; 13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return DTM.NULL; 13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The getUnparsedEntityURI function returns the URI of the unparsed 13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * entity with the specified name in the same document as the context 13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * node (see [3.3 Unparsed Entities]). It returns the empty string if 13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * there is no such entity. 13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * XML processors may choose to use the System Identifier (if one 13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is provided) to resolve the entity, rather than the URI in the 13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Public Identifier. The details are dependent on the processor, and 13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * we would have to support some form of plug-in resolver to handle 13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * this properly. Currently, we simply return the System Identifier if 13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * present, and hope that it a usable URI or that our caller can 13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * map it to one. 13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * TODO: Resolve Public Identifiers... or consider changing function name. 13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * If we find a relative URI 13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * reference, XML expects it to be resolved in terms of the base URI 13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the document. The DOM doesn't do that for us, and it isn't 13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * entirely clear whether that should be done here; currently that's 13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * pushed up to a higher level of our application. (Note that DOM Level 13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1 didn't store the document's base URI.) 14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * TODO: Consider resolving Relative URIs. 14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * (The DOM's statement that "An XML processor may choose to 14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * completely expand entities before the structure model is passed 14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to the DOM" refers only to parsed entities, not unparsed, and hence 14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * doesn't affect this function.) 14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param name A string containing the Entity Name of the unparsed 14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * entity. 14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return String containing the URI of the Unparsed Entity, or an 14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * empty string if no such entity exists. 14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String getUnparsedEntityURI(String name) 14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String url = ""; 14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) 14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ? (Document) m_root : m_root.getOwnerDocument(); 14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != doc) 14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DocumentType doctype = doc.getDoctype(); 14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != doctype) 14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson NamedNodeMap entities = doctype.getEntities(); 14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null == entities) 14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return url; 14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Entity entity = (Entity) entities.getNamedItem(name); 14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null == entity) 14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return url; 14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String notationName = entity.getNotationName(); 14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != notationName) // then it's unparsed 14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // The draft says: "The XSLT processor may use the public 14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // identifier to generate a URI for the entity instead of the URI 14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // specified in the system identifier. If the XSLT processor does 14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // not use the public identifier to generate the URI, it must use 14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the system identifier; if the system identifier is a relative 14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // URI, it must be resolved into an absolute URI using the URI of 14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the resource containing the entity declaration as the base 14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // URI [RFC2396]." 14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // So I'm falling a bit short here. 14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson url = entity.getSystemId(); 14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == url) 14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson url = entity.getPublicId(); 14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This should be resolved to an absolute URL, but that's hard 14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to do from here. 14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return url; 14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5. [specified] A flag indicating whether this attribute was actually 14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified in the start-tag of its element, or was defaulted from the 14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DTD. 14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param attributeHandle the attribute handle 14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return <code>true</code> if the attribute was specified; 14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>false</code> if it was defaulted. 14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public boolean isAttributeSpecified(int attributeHandle) 14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = getNodeType(attributeHandle); 14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (DTM.ATTRIBUTE_NODE == type) 14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Attr attr = (Attr)getNode(attributeHandle); 14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return attr.getSpecified(); 14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Bind an IncrementalSAXSource to this DTM. NOT RELEVANT for DOM2DTM, since 14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * we're wrapped around an existing DOM. 14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param source The IncrementalSAXSource that we want to recieve events from 14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * on demand. 14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setIncrementalSAXSource(IncrementalSAXSource source) 14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** getContentHandler returns "our SAX builder" -- the thing that 14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * someone else should send SAX events to in order to extend this 14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DTM model. 14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to SAX events, 15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * "this" if the DTM object has a built-in SAX ContentHandler, 15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the IncrmentalSAXSource if we're bound to one and should receive 15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the SAX stream via it for incremental build purposes... 15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.ContentHandler getContentHandler() 15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return this DTM's lexical handler. 15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% Should this return null if constrution already done/begun? 15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to lexical SAX events, 15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * "this" if the DTM object has a built-in SAX ContentHandler, 15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the IncrementalSAXSource if we're bound to one and should receive 15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the SAX stream via it for incremental build purposes... 15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.ext.LexicalHandler getLexicalHandler() 15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return this DTM's EntityResolver. 15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to SAX entity ref events. 15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.EntityResolver getEntityResolver() 15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return this DTM's DTDHandler. 15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to SAX dtd events. 15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.DTDHandler getDTDHandler() 15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return this DTM's ErrorHandler. 15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to SAX error events. 15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.ErrorHandler getErrorHandler() 15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Return this DTM's DeclHandler. 15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null if this model doesn't respond to SAX Decl events. 15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public org.xml.sax.ext.DeclHandler getDeclHandler() 15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** @return true iff we're building this model incrementally (eg 15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * we're partnered with a IncrementalSAXSource) and thus require that the 15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * transformation and the parse run simultaneously. Guidance to the 15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DTMManager. 15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public boolean needsTwoThreads() 15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ========== Direct SAX Dispatch, for optimization purposes ======== 15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition 15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of whitespace. Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S"> 15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the definition of <CODE>S</CODE></A> for details. 15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param ch Character to check as XML whitespace. 15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return =true if <var>ch</var> is XML whitespace; otherwise =false. 15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static boolean isSpace(char ch) 15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return XMLCharacterRecognizer.isWhiteSpace(ch); // Take the easy way out for now. 15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Directly call the 15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * characters method on the passed ContentHandler for the 15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * string-value of the given node (see http://www.w3.org/TR/xpath#data-model 15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for the definition of a node's string-value). Multiple calls to the 15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ContentHandler's characters methods may well occur for a single call to 16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * this method. 16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node ID. 16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param ch A non-null reference to a ContentHandler. 16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws org.xml.sax.SAXException 16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void dispatchCharactersEvents( 16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nodeHandle, org.xml.sax.ContentHandler ch, 16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean normalize) 16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(normalize) 16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XMLString str = getStringValue(nodeHandle); 16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson str = str.fixWhiteSpace(true, true, false); 16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson str.dispatchCharactersEvents(ch); 16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int type = getNodeType(nodeHandle); 16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dispatchNodeData(node, ch, 0); 16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Text coalition -- a DTM text node may represent multiple 16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // DOM nodes. 16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(TEXT_NODE == type || CDATA_SECTION_NODE == type) 16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while( null != (node=logicalNextDOMTextNode(node)) ) 16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dispatchNodeData(node, ch, 0); 16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Retrieve the text content of a DOM subtree, appending it into a 16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * user-supplied FastStringBuffer object. Note that attributes are 16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not considered part of the content of an element. 16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * There are open questions regarding whitespace stripping. 16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Currently we make no special effort in that regard, since the standard 16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DOM doesn't yet provide DTD-based information to distinguish 16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * whitespace-in-element-context from genuine #PCDATA. Note that we 16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * should probably also consider xml:space if/when we address this. 16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * DOM Level 3 may solve the problem for us. 16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %REVIEW% Note that as a DOM-level operation, it can be argued that this 16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * routine _shouldn't_ perform any processing beyond what the DOM already 16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * does, and that whitespace stripping and so on belong at the DTM level. 16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * If you want a stripped DOM view, wrap DTM2DOM around DOM2DTM. 16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node Node whose subtree is to be walked, gathering the 16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * contents of all Text or CDATASection nodes. 16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected static void dispatchNodeData(Node node, 16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.xml.sax.ContentHandler ch, 16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int depth) 16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson switch (node.getNodeType()) 16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.DOCUMENT_FRAGMENT_NODE : 16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.DOCUMENT_NODE : 16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.ELEMENT_NODE : 16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (Node child = node.getFirstChild(); null != child; 16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson child = child.getNextSibling()) 16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dispatchNodeData(child, ch, depth+1); 16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.PROCESSING_INSTRUCTION_NODE : // %REVIEW% 16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.COMMENT_NODE : 16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(0 != depth) 16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // NOTE: Because this operation works in the DOM space, it does _not_ attempt 16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to perform Text Coalition. That should only be done in DTM space. 16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.TEXT_NODE : 16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.CDATA_SECTION_NODE : 16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson case Node.ATTRIBUTE_NODE : 16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String str = node.getNodeValue(); 16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(ch instanceof CharacterNodeHandler) 16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ((CharacterNodeHandler)ch).characters(node); 16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ch.characters(str.toCharArray(), 0, str.length()); 16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// /* case Node.PROCESSING_INSTRUCTION_NODE : 16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING); 16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// break; */ 16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson default : 16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ignore 16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson TreeWalker m_walker = new TreeWalker(null); 17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Directly create SAX parser events from a subtree. 17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nodeHandle The node ID. 17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param ch A non-null reference to a ContentHandler. 17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws org.xml.sax.SAXException 17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) 17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson TreeWalker treeWalker = m_walker; 17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ContentHandler prevCH = treeWalker.getContentHandler(); 17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null != prevCH) 17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson treeWalker = new TreeWalker(null); 17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson treeWalker.setContentHandler(ch); 17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Node node = getNode(nodeHandle); 17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson treeWalker.traverseFragment(node); 17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson finally 17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson treeWalker.setContentHandler(null); 17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public interface CharacterNodeHandler 17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void characters(Node node) 17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException; 17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * For the moment all the run time properties are ignored by this 17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * class. 17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param property a <code>String</code> value 17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param value an <code>Object</code> value 17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setProperty(String property, Object value) 17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * No source information is available for DOM2DTM, so return 17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>null</code> here. 17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param node an <code>int</code> value 17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return null 17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public SourceLocator getSourceLocatorFor(int node) 17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1767