📄 saxhandler.java
字号:
/* SAXHandler.java{{IS_NOTE Purpose: Description: History: 2001/10/25 12:34:46, Create, Tom M. Yeh.}}IS_NOTECopyright (C) 2001 Potix Corporation. All Rights Reserved.{{IS_RIGHT This program is distributed under GPL Version 2.0 in the hope that it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.idom.input;import java.util.Stack;import java.util.List;import java.util.LinkedList;import java.util.Map;import java.util.HashMap;import java.util.Iterator;import java.io.IOException;import java.net.URL;import javax.xml.parsers.SAXParser;import org.xml.sax.Locator;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.InputSource;import org.xml.sax.EntityResolver;import org.xml.sax.ErrorHandler;import org.xml.sax.ext.LexicalHandler;import org.xml.sax.ext.DeclHandler;import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.XMLReader;import org.zkoss.lang.D;import org.zkoss.lang.Objects;import org.zkoss.util.logging.Log;import org.zkoss.util.resource.Locators;import org.zkoss.idom.util.SimpleLocator;import org.zkoss.idom.*;/** * The SAX Hanlder. * It implements ContentHandler, LexicalHandler and DeclHandler. * It is the caller's job to set up this handler properly if required. * * <p>This class doesn't depend on SAXBuilder, so it can be used in any * other place, e.g., javax.xml.transform.sax.SAXResult. * * @author tomyeh * @see SAXBuilder */public class SAXHandler extends DefaultHandlerimplements LexicalHandler, DeclHandler { private static final Log log = Log.lookup(SAXHandler.class); /** The iDOM factory. */ protected IDOMFactory _factory; //-- options --// /** Whether to ignore ignorable whitespace */ private boolean _ignoreWhitespaces = false; /** Whether expansion of entities should occur */ private boolean _expandEntities = true; /** Whether to convert CDATA to Text and coalesce them. */ private boolean _coalescing = false; /** Whether to ignore comments. */ private boolean _ignoreComments = false; /** The error handler. */ private ErrorHandler _errHandler = null; /** The entity resolver. */ private EntityResolver _resolver = null; /** The Document being created. */ protected Document _doc = null; /** Locator. */ protected Locator _loc = null; /** Indicator of whether we are in a DTD. */ protected boolean _inDTD = false; /** Indicator of whether we are in a CDATA. */ protected boolean _inCData = false; /** The Group stack. The top one is the current group being processed. */ protected Stack _stack = null; /** The namespaces in between startPrefixMapping and endPrefixMapping. */ protected List _declNamespaces = null; /** Temporary holder for the internal subset. */ private StringBuffer _internSubset = null; /** Whether it is in internal subset. */ private boolean _inInternSubset = false; /** * Constructor. * * @param factory the iDOM factory; null for DefaultIDOMFactory. */ public SAXHandler(IDOMFactory factory) { _factory = factory != null ? factory: new DefaultIDOMFactory(); } /** * Constructor. */ public SAXHandler() { _factory = new DefaultIDOMFactory(); } //-- options --// /** * Tests whether to ignore whitespaces in element content. */ public final boolean isIgnoringElementContentWhitespace() { return _ignoreWhitespaces; } /** * Sets whether the parser should elminate whitespace in * element content. They are known as "ignorable whitespace". * Only whitespace which is contained within element content that has * an element only content model will be eliminated (see XML Rec 2.10). * * <p>For this setting to take effect requires that validation be turned on. * * <p>Default: false. * * @param ignore Whether to ignore whitespaces in element content. */ public final void setIgnoringElementContentWhitespace(boolean ignore) { _ignoreWhitespaces = ignore; } /** * Tests whether to expand entity reference nodes. */ public final boolean isExpandEntityReferences() { return _expandEntities; } /** * Sets whether to expand entities during parsing. * A true means to expand entities as normal content. A false means to * leave entities unexpanded as <code>EntityReference</code> objects. * * <p>Default: true. * * @param expand whether entity expansion should occur. */ public final void setExpandEntityReferences(boolean expand) { _expandEntities = expand; } /** * Indicates whether or not the factory is configured to produce parsers * which converts CDATA to Text and appends it to the adjacent (if any) * Text node. * * <p>Default: false. * * @return true if the factory is configured to produce parsers which * converts CDATA nodes to Text nodes * and appends it to the adjacent (if any) Text node; false otherwise. */ public final boolean isCoalescing() { return _coalescing; } /** * Specifies that the parser produced by this code will convert * CDATA to Text and append it to the adjacent (if any) text. * * <p>Default: false. */ public final void setCoalescing(boolean coalescing) { _coalescing = coalescing; } /** * Indicates whether or not the factory is configured to produce parsers * which ignores comments. * * <p>Default: false. * * @return true if the factory is configured to produce parsers * which ignores comments; false otherwise. */ public final boolean isIgnoringComments() { return _ignoreComments; } /** * Specifies that the parser produced by this code will ignore comments. * * <p>Default: false. */ public final void setIgnoringComments(boolean ignoreComments) { _ignoreComments = ignoreComments; } /** * Specifies the org.xml.sax.ErrorHandler to be used to report errors * present in the XML document to be parsed. * <p>Default: null -- to use the default imple-mentation and behavior. */ public final void setErrorHandler(ErrorHandler eh) { _errHandler = eh; } /** * Gets the org.xml.sax.ErrorHandler. * * @return the error handler; null to use the default implementation */ public final ErrorHandler getErrorHandler() { return _errHandler; } /** * Specifies the org.xml.sax.EntityResolver to be used to resolve * entities present in the XML docu-ment to be parsed. * <p>Default: null -- to use the default implementation and behavior. */ public final void setEntityResolver(org.xml.sax.EntityResolver er) { _resolver = er; } /** * Gets the org.xml.sax.EntityResolver. * * @return the enity resolverr; null to use the default implementation */ public final EntityResolver getEntityResolver() { return _resolver; } //-- Extra utilities for the caller to use --// /** * Gets the document being created. * Called to retrieve the iDOM tree after parsed. */ public final Document getDocument() { return _doc; } /** * Gets the iDOM factory. Null for DefaultIDOMFactory.THE. */ public final IDOMFactory getIDOMFactory() { return _factory; } /** * Sets the iDOM factory. Null for DefaultIDOMFactory.THE. */ public final void setIDOMFactory(IDOMFactory factory) { _factory = factory; } //-- protected utilities --// /** * Attaches the locator to the item. */ protected final void attachLocator(Item vtx) { if (_loc != null) vtx.setLocator(new SimpleLocator(_loc)); } /** Returns the top group, or null if not available. */ protected final Group getTopGroup() { return _stack.isEmpty() ? null: (Group)_stack.peek(); } /** * Adds the item to the current group; also attach the locator. */ protected final void addToCurrentGroup(Item vtx) { attachLocator(vtx); ((Group)_stack.peek()).getChildren().add(vtx); } /** * Adds a new group to the current group as a child, * and pushes the new group to be the new current group. */ protected final void pushGroup(Group group) { if (_stack.isEmpty()) assert(group instanceof Document); else addToCurrentGroup(group); _stack.push(group); } /** * Pops out the current group, and the one under it becomes the * new current group. */ protected final void popGroup() { ((Group)_stack.pop()).coalesce(false); } //-- org.xml.sax.ext.DeclHandler --// public void externalEntityDecl(String name, String pubId, String sysId) throws SAXException { if (D.ON && log.finerable()) log.finer("externalEntityDecl: " + name + " p:" + pubId + " s:" + sysId); if (!_inInternSubset) return; _internSubset.append(" <!ENTITY ").append(name); if (pubId != null) _internSubset.append(" PUBLIC \"").append(pubId).append("\" "); if (sysId != null) _internSubset.append(" SYSTEM \"").append(sysId).append("\" "); _internSubset.append(">\n"); } public void internalEntityDecl(String name, String value) throws SAXException { if (D.ON && log.finerable()) log.finer("internalEntityDecl: " + name + '=' + value); if (!_inInternSubset) return; _internSubset.append(" <!ENTITY ").append(name).append(" \"") .append(value).append("\">\n"); } public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) throws SAXException { if (!_inInternSubset) return; _internSubset.append(" <!ATTLIST ").append(eName).append(' ') .append(aName).append(' ').append(type).append(' '); if (valueDefault != null) { _internSubset.append(valueDefault); } else { _internSubset.append('"').append(value).append('"'); } if ((valueDefault != null) && (valueDefault.equals("#FIXED"))) { _internSubset.append(" \"").append(value).append('"'); } _internSubset.append(">\n"); } public void elementDecl(String name, String model) throws SAXException { if (!_inInternSubset) return; _internSubset.append(" <!ELEMENT ").append(name).append(' ') .append(model).append(">\n"); } //-- org.xml.sax.ext.LexicalHandler --// public void startDTD(String name, String pubId, String sysId) throws SAXException { if (D.ON && log.finerable()) log.finer("start DTD: " + name + " p:" + pubId + " s:" + sysId); addToCurrentGroup(_factory.newDocType(name, pubId, sysId)); _inDTD = true; _internSubset = new StringBuffer(); //TY: start use it _inInternSubset = true; } //NOTE: xerces does not invoke endDTD if nothing in there public void endDTD() throws SAXException { if (D.ON && log.finerable()) log.finer("end DTD: \"" + _internSubset + '"'); _doc.getDocType().setInternalSubset(_internSubset.toString()); _inDTD = false; _internSubset = null; //TY: no longer used _inInternSubset = false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -