dom2dtm.java
来自「Mobile 应用程序使用 Java Micro Edition (Java M」· Java 代码 · 共 1,764 行 · 第 1/4 页
JAVA
1,764 行
/** * Returns the <code>Element</code> whose <code>ID</code> is given by * <code>elementId</code>. If no such element exists, returns * <code>DTM.NULL</code>. Behavior is not defined if more than one element * has this <code>ID</code>. Attributes (including those * with the name "ID") are not of type ID unless so defined by DTD/Schema * information available to the DTM implementation. * Implementations that do not know whether attributes are of type ID or * not are expected to return <code>DTM.NULL</code>. * * <p>%REVIEW% Presumably IDs are still scoped to a single document, * and this operation searches only within a single document, right? * Wouldn't want collisions between DTMs in the same process.</p> * * @param elementId The unique <code>id</code> value for an element. * @return The handle of the matching element. */ public int getElementById(String elementId) { Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) ? (Document) m_root : m_root.getOwnerDocument(); if(null != doc) { Node elem = doc.getElementById(elementId); if(null != elem) { int elemHandle = getHandleFromNode(elem); if(DTM.NULL == elemHandle) { int identity = m_nodes.size()-1; while (DTM.NULL != (identity = getNextNodeIdentity(identity))) { Node node = getNode(identity); if(node == elem) { elemHandle = getHandleFromNode(elem); break; } } } return elemHandle; } } return DTM.NULL; } /** * 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 = ""; Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE) ? (Document) m_root : m_root.getOwnerDocument(); if (null != doc) { DocumentType doctype = doc.getDoctype(); if (null != doctype) { NamedNodeMap entities = doctype.getEntities(); if(null == entities) return url; Entity entity = (Entity) entities.getNamedItem(name); if(null == entity) return url; String notationName = entity.getNotationName(); if (null != notationName) // then it's unparsed { // 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 = entity.getSystemId(); if (null == url) { url = entity.getPublicId(); } else { // This should be resolved to an absolute URL, but that's hard // to do from here. } } } } return url; } /** * 5. [specified] A flag indicating whether this attribute was actually * specified in the start-tag of its element, or was defaulted from the * DTD. * * @param attributeHandle the attribute handle * @return <code>true</code> if the attribute was specified; * <code>false</code> if it was defaulted. */ public boolean isAttributeSpecified(int attributeHandle) { int type = getNodeType(attributeHandle); if (DTM.ATTRIBUTE_NODE == type) { Attr attr = (Attr)getNode(attributeHandle); return attr.getSpecified(); } return false; } /** Bind an IncrementalSAXSource to this DTM. NOT RELEVANT for DOM2DTM, since * we're wrapped around an existing DOM. * * @param source The IncrementalSAXSource that we want to recieve events from * on demand. */ public void setIncrementalSAXSource(IncrementalSAXSource source) { } /** getContentHandler returns "our SAX builder" -- the thing that * someone else should send SAX events to in order to extend this * DTM model. * * @return null if this model doesn't respond to SAX events, * "this" if the DTM object has a built-in SAX ContentHandler, * the IncrmentalSAXSource if we're bound to one and should receive * the SAX stream via it for incremental build purposes... * */ public org.xml.sax.ContentHandler getContentHandler() { return null; } /** * Return this DTM's lexical handler. * * %REVIEW% Should this return null if constrution already done/begun? * * @return null if this model doesn't respond to lexical SAX events, * "this" if the DTM object has a built-in SAX ContentHandler, * the IncrementalSAXSource if we're bound to one and should receive * the SAX stream via it for incremental build purposes... */ public org.xml.sax.ext.LexicalHandler getLexicalHandler() { return null; } /** * Return this DTM's EntityResolver. * * @return null if this model doesn't respond to SAX entity ref events. */ public org.xml.sax.EntityResolver getEntityResolver() { return null; } /** * Return this DTM's DTDHandler. * * @return null if this model doesn't respond to SAX dtd events. */ public org.xml.sax.DTDHandler getDTDHandler() { return null; } /** * Return this DTM's ErrorHandler. * * @return null if this model doesn't respond to SAX error events. */ public org.xml.sax.ErrorHandler getErrorHandler() { return null; } /** * Return this DTM's DeclHandler. * * @return null if this model doesn't respond to SAX Decl events. */ public org.xml.sax.ext.DeclHandler getDeclHandler() { return null; } /** @return true iff we're building this model incrementally (eg * we're partnered with a IncrementalSAXSource) and thus require that the * transformation and the parse run simultaneously. Guidance to the * DTMManager. * */ public boolean needsTwoThreads() { return false; } // ========== Direct SAX Dispatch, for optimization purposes ======== /** * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition * of whitespace. Refer to <A href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S"> * the definition of <CODE>S</CODE></A> for details. * @param ch Character to check as XML whitespace. * @return =true if <var>ch</var> is XML whitespace; otherwise =false. */ private static boolean isSpace(char ch) { return XMLCharacterRecognizer.isWhiteSpace(ch); // Take the easy way out for now. } /** * Directly call the * characters method on the passed ContentHandler for the * string-value of the given node (see http://www.w3.org/TR/xpath#data-model * for the definition of a node's string-value). Multiple calls to the * ContentHandler's characters methods may well occur for a single call to * this method. * * @param nodeHandle The node ID. * @param ch A non-null reference to a ContentHandler. * * @throws org.xml.sax.SAXException */ public void dispatchCharactersEvents( int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize) throws org.xml.sax.SAXException { if(normalize) { XMLString str = getStringValue(nodeHandle); str = str.fixWhiteSpace(true, true, false); str.dispatchCharactersEvents(ch); } else { int type = getNodeType(nodeHandle); Node node = getNode(nodeHandle); dispatchNodeData(node, ch, 0); // Text coalition -- a DTM text node may represent multiple // DOM nodes. if(TEXT_NODE == type || CDATA_SECTION_NODE == type) { while( null != (node=logicalNextDOMTextNode(node)) ) { dispatchNodeData(node, ch, 0); } } } } /** * Retrieve the text content of a DOM subtree, appending it into a * user-supplied FastStringBuffer object. Note that attributes are * not considered part of the content of an element. * <p> * There are open questions regarding whitespace stripping. * Currently we make no special effort in that regard, since the standard * DOM doesn't yet provide DTD-based information to distinguish * whitespace-in-element-context from genuine #PCDATA. Note that we * should probably also consider xml:space if/when we address this. * DOM Level 3 may solve the problem for us. * <p> * %REVIEW% Note that as a DOM-level operation, it can be argued that this * routine _shouldn't_ perform any processing beyond what the DOM already * does, and that whitespace stripping and so on belong at the DTM level. * If you want a stripped DOM view, wrap DTM2DOM around DOM2DTM. * * @param node Node whose subtree is to be walked, gathering the * contents of all Text or CDATASection nodes. */ protected static void dispatchNodeData(Node node, org.xml.sax.ContentHandler ch, int depth) throws org.xml.sax.SAXException { switch (node.getNodeType()) { case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : case Node.ELEMENT_NODE : { for (Node child = node.getFirstChild(); null != child; child = child.getNextSibling()) { dispatchNodeData(child, ch, depth+1); } } break; case Node.PROCESSING_INSTRUCTION_NODE : // %REVIEW% case Node.COMMENT_NODE : if(0 != depth) break; // NOTE: Because this operation works in the DOM space, it does _not_ attempt // to perform Text Coalition. That should only be done in DTM space. case Node.TEXT_NODE : case Node.CDATA_SECTION_NODE : case Node.ATTRIBUTE_NODE : String str = node.getNodeValue(); if(ch instanceof CharacterNodeHandler) { ((CharacterNodeHandler)ch).characters(node); } else { ch.characters(str.toCharArray(), 0, str.length()); } break;// /* case Node.PROCESSING_INSTRUCTION_NODE :// // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING); // break; */ default : // ignore break; } } TreeWalker m_walker = new TreeWalker(null); /** * Directly create SAX parser events from a subtree. * * @param nodeHandle The node ID. * @param ch A non-null reference to a ContentHandler. * * @throws org.xml.sax.SAXException */ public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) throws org.xml.sax.SAXException { TreeWalker treeWalker = m_walker; ContentHandler prevCH = treeWalker.getContentHandler(); if(null != prevCH) { treeWalker = new TreeWalker(null); } treeWalker.setContentHandler(ch); try { Node node = getNode(nodeHandle); treeWalker.traverse(node); } finally { treeWalker.setContentHandler(null); } } public interface CharacterNodeHandler { public void characters(Node node) throws org.xml.sax.SAXException; } /** * For the moment all the run time properties are ignored by this * class. * * @param property a <code>String</code> value * @param value an <code>Object</code> value */ public void setProperty(String property, Object value) { } /** * No source information is available for DOM2DTM, so return * <code>null</code> here. * * @param node an <code>int</code> value * @return null */ public SourceLocator getSourceLocatorFor(int node) { return null; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?