sax2dtm.java
来自「JAVA 所有包」· Java 代码 · 共 2,129 行 · 第 1/5 页
JAVA
2,129 行
* Construct the node map from the node. * * @param type raw type ID, one of DTM.XXX_NODE. * @param expandedTypeID The expended type ID. * @param parentIndex The current parent index. * @param previousSibling The previous sibling index. * @param dataOrPrefix index into m_data table, or string handle. * @param canHaveFirstChild true if the node can have a first child, false * if it is atomic. * * @return The index identity of the node that was added. */ protected int addNode(int type, int expandedTypeID, int parentIndex, int previousSibling, int dataOrPrefix, boolean canHaveFirstChild) { // Common to all nodes: int nodeIndex = m_size++; // Have we overflowed a DTM Identity's addressing range? if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS)) { addNewDTMID(nodeIndex); } m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL); m_nextsib.addElement(NOTPROCESSED); m_parent.addElement(parentIndex); m_exptype.addElement(expandedTypeID); m_dataOrQName.addElement(dataOrPrefix); if (m_prevsib != null) { m_prevsib.addElement(previousSibling); } if (DTM.NULL != previousSibling) { m_nextsib.setElementAt(nodeIndex,previousSibling); } if (m_locator != null && m_useSourceLocationProperty) { setSourceLocation(); } // Note that nextSibling is not processed until charactersFlush() // is called, to handle successive characters() events. // Special handling by type: Declare namespaces, attach first child switch(type) { case DTM.NAMESPACE_NODE: declareNamespaceInContext(parentIndex,nodeIndex); break; case DTM.ATTRIBUTE_NODE: break; default: if (DTM.NULL == previousSibling && DTM.NULL != parentIndex) { m_firstch.setElementAt(nodeIndex,parentIndex); } break; } return nodeIndex; } /** * Get a new DTM ID beginning at the specified node index. * @param nodeIndex The node identity at which the new DTM ID will begin * addressing. */ protected void addNewDTMID(int nodeIndex) { try { if(m_mgr==null) throw new ClassCastException(); // Handle as Extended Addressing DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr; int id=mgrD.getFirstFreeDTMID(); mgrD.addDTM(this,id,nodeIndex); m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS); } catch(ClassCastException e) { // %REVIEW% Wrong error message, but I've been told we're trying // not to add messages right not for I18N reasons. // %REVIEW% Should this be a Fatal Error? error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null));//"No more DTM IDs are available"; } } /** * Migrate a DTM built with an old DTMManager to a new DTMManager. * After the migration, the new DTMManager will treat the DTM as * one that is built by itself. * This is used to support DTM sharing between multiple transformations. * @param manager the DTMManager */ public void migrateTo(DTMManager manager) { super.migrateTo(manager); // We have to reset the information in m_dtmIdent and // register the DTM with the new manager. int numDTMs = m_dtmIdent.size(); int dtmId = m_mgrDefault.getFirstFreeDTMID(); int nodeIndex = 0; for (int i = 0; i < numDTMs; i++) { m_dtmIdent.setElementAt(dtmId << DTMManager.IDENT_DTM_NODE_BITS, i); m_mgrDefault.addDTM(this, dtmId, nodeIndex); dtmId++; nodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS); } } /** * Store the source location of the current node. This method must be called * as every node is added to the DTM or for no node. */ protected void setSourceLocation() { m_sourceSystemId.addElement(m_locator.getSystemId()); m_sourceLine.addElement(m_locator.getLineNumber()); m_sourceColumn.addElement(m_locator.getColumnNumber()); //%REVIEW% %BUG% Prevent this from arising in the first place // by not allowing the enabling conditions to change after we start // building the document. if (m_sourceSystemId.size() != m_size) { String msg = "CODING ERROR in Source Location: " + m_size + " != " + m_sourceSystemId.size(); System.err.println(msg); throw new RuntimeException(msg); } } /** * Given a node handle, return its node value. This is mostly * as defined by the DOM, but may ignore some conveniences. * <p> * * @param nodeHandle The node id. * @return String Value of this node, or null if not * meaningful for this node type. */ public String getNodeValue(int nodeHandle) { int identity = makeNodeIdentity(nodeHandle); int type = _type(identity); if (isTextType(type)) { int dataIndex = _dataOrQName(identity); int offset = m_data.elementAt(dataIndex); int length = m_data.elementAt(dataIndex + 1); // %OPT% We should cache this, I guess. return m_chars.getString(offset, length); } else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type || DTM.DOCUMENT_NODE == type) { return null; } else { int dataIndex = _dataOrQName(identity); if (dataIndex < 0) { dataIndex = -dataIndex; dataIndex = m_data.elementAt(dataIndex + 1); } return m_valuesOrPrefixes.indexToString(dataIndex); } } /** * Given a node handle, return its XPath-style localname. * (As defined in Namespaces, this is the portion of the name after any * colon character). * * @param nodeHandle the id of the node. * @return String Local name of this node. */ public String getLocalName(int nodeHandle) { return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle))); } /** * The getUnparsedEntityURI function returns the URI of the unparsed * entity with the specified name in the same document as the context * node (see [3.3 Unparsed Entities]). It returns the empty string if * there is no such entity. * <p> * XML processors may choose to use the System Identifier (if one * is provided) to resolve the entity, rather than the URI in the * Public Identifier. The details are dependent on the processor, and * we would have to support some form of plug-in resolver to handle * this properly. Currently, we simply return the System Identifier if * present, and hope that it a usable URI or that our caller can * map it to one. * TODO: Resolve Public Identifiers... or consider changing function name. * <p> * If we find a relative URI * reference, XML expects it to be resolved in terms of the base URI * of the document. The DOM doesn't do that for us, and it isn't * entirely clear whether that should be done here; currently that's * pushed up to a higher level of our application. (Note that DOM Level * 1 didn't store the document's base URI.) * TODO: Consider resolving Relative URIs. * <p> * (The DOM's statement that "An XML processor may choose to * completely expand entities before the structure model is passed * to the DOM" refers only to parsed entities, not unparsed, and hence * doesn't affect this function.) * * @param name A string containing the Entity Name of the unparsed * entity. * * @return String containing the URI of the Unparsed Entity, or an * empty string if no such entity exists. */ public String getUnparsedEntityURI(String name) { String url = ""; if (null == m_entities) return url; int n = m_entities.size(); for (int i = 0; i < n; i += ENTITY_FIELDS_PER) { String ename = (String) m_entities.elementAt(i + ENTITY_FIELD_NAME); if (null != ename && ename.equals(name)) { String nname = (String) m_entities.elementAt(i + ENTITY_FIELD_NOTATIONNAME); if (null != nname) { // The draft says: "The XSLT processor may use the public // identifier to generate a URI for the entity instead of the URI // specified in the system identifier. If the XSLT processor does // not use the public identifier to generate the URI, it must use // the system identifier; if the system identifier is a relative // URI, it must be resolved into an absolute URI using the URI of // the resource containing the entity declaration as the base // URI [RFC2396]." // So I'm falling a bit short here. url = (String) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID); if (null == url) { url = (String) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID); } } break; } } return url; } /** * Given a namespace handle, return the prefix that the namespace decl is * mapping. * Given a node handle, return the prefix used to map to the namespace. * * <p> %REVIEW% Are you sure you want "" for no prefix? </p> * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb </p> * * @param nodeHandle the id of the node. * @return String prefix of this node's name, or "" if no explicit * namespace prefix was given. */ public String getPrefix(int nodeHandle) { int identity = makeNodeIdentity(nodeHandle); int type = _type(identity); if (DTM.ELEMENT_NODE == type) { int prefixIndex = _dataOrQName(identity); if (0 == prefixIndex) return ""; else { String qname = m_valuesOrPrefixes.indexToString(prefixIndex); return getPrefix(qname, null); } } else if (DTM.ATTRIBUTE_NODE == type) { int prefixIndex = _dataOrQName(identity); if (prefixIndex < 0) { prefixIndex = m_data.elementAt(-prefixIndex); String qname = m_valuesOrPrefixes.indexToString(prefixIndex); return getPrefix(qname, null); } } return ""; } /** * Retrieves an attribute node by by qualified name and namespace URI. * * @param nodeHandle int Handle of the node upon which to look up this attribute.. * @param namespaceURI The namespace URI of the attribute to * retrieve, or null. * @param name The local name of the attribute to * retrieve. * @return The attribute node handle with the specified name ( * <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such * attribute. */ public int getAttributeNode(int nodeHandle, String namespaceURI, String name) { for (int attrH = getFirstAttribute(nodeHandle); DTM.NULL != attrH; attrH = getNextAttribute(attrH)) { String attrNS = getNamespaceURI(attrH); String attrName = getLocalName(attrH); boolean nsMatch = namespaceURI == attrNS || (namespaceURI != null && namespaceURI.equals(attrNS)); if (nsMatch && name.equals(attrName)) return attrH; } return DTM.NULL; } /** * Return the public identifier of the external subset, * normalized as described in 4.2.2 External Entities [XML]. If there is * no external subset or if it has no public identifier, this property * has no value. * * @return the public identifier String object, or null if there is none. */ public String getDocumentTypeDeclarationPublicIdentifier() { /** @todo: implement this com.sun.org.apache.xml.internal.dtm.DTMDefaultBase abstract method */ error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!"); return null; } /** * Given a node handle, return its DOM-style namespace URI * (As defined in Namespaces, this is the declared URI which this node's * prefix -- or default in lieu thereof -- was mapped to.) * * <p>%REVIEW% Null or ""? -sb</p> * * @param nodeHandle the id of the node. * @return String URI value of this node's namespace, or null if no * namespace was resolved. */ public String getNamespaceURI(int nodeHandle) { return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle))); } /** * Get the string-value of a node as a String object * (see http://www.w3.org/TR/xpath#data-model * for the definition of a node's string-value). * * @param nodeHandle The node ID. * * @return A string object that represents the string-value of the given node. */ public XMLString getStringValue(int nodeHandle) { int identity = makeNodeIdentity(nodeHandle); int type; if(identity==DTM.NULL) // Separate lines because I wanted to breakpoint it type = DTM.NULL; else type= _type(identity); if (isTextType(type)) { int dataIndex = _dataOrQName(identity); int offset = m_data.elementAt(dataIndex); int length = m_data.elementAt(dataIndex + 1); return m_xstrf.newstr(m_chars, offset, length); } else { int firstChild = _firstch(identity); if (DTM.NULL != firstChild) { int offset = -1; int length = 0; int startNode = identity; identity = firstChild; do { type = _type(identity); if (isTextType(type))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?