xincludefilter.java
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 570 行 · 第 1/2 页
JAVA
570 行
/* * Copyright (C) 2001-2002 David Brownell * * This file is part of GNU JAXP, a library. * * GNU JAXP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GNU JAXP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception, if you link this library with other files to * produce an executable, this library does not by itself cause the * resulting executable to be covered by the GNU General Public License. * This exception does not however invalidate any other reasons why the * executable file might be covered by the GNU General Public License. */package gnu.xml.pipeline;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL; import java.net.URLConnection; import java.util.Enumeration;import java.util.Hashtable;import java.util.Stack;import java.util.Vector;import org.xml.sax.Attributes;import org.xml.sax.ErrorHandler;import org.xml.sax.InputSource;import org.xml.sax.Locator;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.XMLReaderFactory;import gnu.xml.util.Resolver;/** * Filter to process an XPointer-free subset of * <a href="http://www.w3.org/TR/xinclude">XInclude</a>, supporting its * use as a kind of replacement for parsed general entities. * XInclude works much like the <code>#include</code> of C/C++ but * works for XML documents as well as unparsed text files. * Restrictions from the 17-Sept-2002 CR draft of XInclude are as follows: * * <ul> * * <li> URIs must not include fragment identifiers. * The CR specifies support for XPointer <em>element()</em> fragment IDs, * which is not currently implemented here. * * <li> <em>xi:fallback</em> handling of resource errors is not * currently supported. * * <li> DTDs are not supported in included files, since the SAX DTD events * must have completely preceded any included file. * The CR explicitly allows the DTD related portions of the infoset to * grow as an effect of including XML documents. * * <li> <em>xml:base</em> fixup isn't done. * * </ul> * * <p> XML documents that are included will normally be processed using * the default SAX namespace rules, meaning that prefix information may * be discarded. This may be changed with {@link #setSavingPrefixes * setSavingPrefixes()}. <em>You are strongly advised to do this.</em> * * <p> Note that XInclude allows highly incompatible implementations, which * are specialized to handle application-specific infoset extensions. Some * such implementations can be implemented by subclassing this one, but * they may only be substituted in applications at "user option". * * <p>TBD: "IURI" handling. * * @author David Brownell */public class XIncludeFilter extends EventFilter implements Locator{ private Hashtable extEntities = new Hashtable (5, 5); private int ignoreCount; private Stack uris = new Stack (); private Locator locator; private Vector inclusions = new Vector (5, 5); private boolean savingPrefixes; /** */ public XIncludeFilter (EventConsumer next) throws SAXException { super (next); setContentHandler (this); // DTDHandler callbacks pass straight through setProperty (DECL_HANDLER, this); setProperty (LEXICAL_HANDLER, this); } private void fatal (SAXParseException e) throws SAXException { ErrorHandler eh; eh = getErrorHandler (); if (eh != null) eh.fatalError (e); throw e; } /** * Passes "this" down the filter chain as a proxy locator. */ public void setDocumentLocator (Locator locator) { this.locator = locator; super.setDocumentLocator (this); } /** Used for proxy locator; do not call directly. */ public String getSystemId () { return (locator == null) ? null : locator.getSystemId (); } /** Used for proxy locator; do not call directly. */ public String getPublicId () { return (locator == null) ? null : locator.getPublicId (); } /** Used for proxy locator; do not call directly. */ public int getLineNumber () { return (locator == null) ? -1 : locator.getLineNumber (); } /** Used for proxy locator; do not call directly. */ public int getColumnNumber () { return (locator == null) ? -1 : locator.getColumnNumber (); } /** * Assigns the flag controlling the setting of the SAX2 * <em>namespace-prefixes</em> flag. */ public void setSavingPrefixes (boolean flag) { savingPrefixes = flag; } /** * Returns the flag controlling the setting of the SAX2 * <em>namespace-prefixes</em> flag when parsing included documents. * The default value is the SAX2 default (false), which discards * information that can be useful. */ public boolean isSavingPrefixes () { return savingPrefixes; } // // Two mechanisms are interacting here. // // - XML Base implies a stack of base URIs, updated both by // "real entity" boundaries and element boundaries. // // - Active "Real Entities" (for document and general entities, // and by xincluded files) are tracked to prevent circular // inclusions. // private String addMarker (String uri) throws SAXException { if (locator != null && locator.getSystemId () != null) uri = locator.getSystemId (); // guard against InputSource objects without system IDs if (uri == null) fatal (new SAXParseException ("Entity URI is unknown", locator)); try { URL url = new URL (uri); uri = url.toString (); if (inclusions.contains (uri)) fatal (new SAXParseException ( "XInclude, circular inclusion", locator)); inclusions.addElement (uri); uris.push (url); } catch (IOException e) { // guard against illegal relative URIs (Xerces) fatal (new SAXParseException ("parser bug: relative URI", locator, e)); } return uri; } private void pop (String uri) { inclusions.removeElement (uri); uris.pop (); } // // Document entity boundaries get both treatments. // public void startDocument () throws SAXException { ignoreCount = 0; addMarker (null); super.startDocument (); } public void endDocument () throws SAXException { inclusions.setSize (0); extEntities.clear (); uris.setSize (0); super.endDocument (); } // // External general entity boundaries get both treatments. // public void externalEntityDecl (String name, String publicId, String systemId) throws SAXException { if (name.charAt (0) == '%') return; try { URL url = new URL (locator.getSystemId ()); systemId = new URL (url, systemId).toString (); } catch (IOException e) { // what could we do? } extEntities.put (name, systemId); } public void startEntity (String name) throws SAXException { if (ignoreCount != 0) { ignoreCount++; return; } String uri = (String) extEntities.get (name); if (uri != null) addMarker (uri); super.startEntity (name); } public void endEntity (String name) throws SAXException { if (ignoreCount != 0) { if (--ignoreCount != 0) return; } String uri = (String) extEntities.get (name); if (uri != null) pop (uri); super.endEntity (name); } // // element boundaries only affect the base URI stack, // unless they're XInclude elements. // public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { if (ignoreCount != 0) { ignoreCount++; return; } URL baseURI = (URL) uris.peek (); String base; base = atts.getValue ("http://www.w3.org/XML/1998/namespace", "base");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?