123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 |
- /* DomParser.java --
- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath 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, or (at your option)
- any later version.
- GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package gnu.xml.util;
- import java.util.Enumeration;
- import java.util.Locale;
- import org.xml.sax.*;
- import org.xml.sax.helpers.AttributesImpl;
- import org.xml.sax.helpers.NamespaceSupport;
- import org.xml.sax.ext.DeclHandler;
- import org.xml.sax.ext.DefaultHandler2;
- import org.xml.sax.ext.LexicalHandler;
- import org.w3c.dom.*;
- /**
- * This parser emits SAX2 parsing events as it traverses a DOM tree, using
- * any conformant implementation of DOM. It exposes all SAX1 features,
- * and the following SAX2 features and properties (as
- * identified by standard URIs which are not fully provided here). Note
- * that if a Level 1 DOM implementation is given, then this behaves as if
- * namespaces were disabled, and namespace prefixes were enabled. </p>
- *
- * <table border="1" width='100%' cellpadding='3' cellspacing='0'>
- * <tr bgcolor='#ccccff'>
- * <th><font size='+1'>Name</font></th>
- * <th><font size='+1'>Notes</font></th></tr>
- *
- * <tr><td colspan=2><center><em>Features ... URL prefix is
- * <b>http://xml.org/sax/features/</b></em></center></td></tr>
- *
- * <tr><td>(URL)/external-general-entities</td>
- * <td>false (does no parsing)</td></tr>
- * <tr><td>(URL)/external-parameter-entities</td>
- * <td>false (does no parsing)</td></tr>
- * <tr><td>(URL)/namespaces</td>
- * <td>Value is fixed at <em>true</em></td></tr>
- * <tr><td>(URL)/namespace-prefixes</td>
- * <td>Value is settable, defaulting to <em>false</em>
- * (<code>xmlns</code> attributes hidden, and names aren't prefixed)
- * </td></tr>
- * <tr><td>(URL)/string-interning</td>
- * <td>Value is fixed at <em>false</em> (DOM provides no
- * guarantees as to interning)</td></tr>
- * <tr><td>(URL)/validation</td>
- * <td>false (does no parsing)</td></tr>
- * <tr><td>(URL)/lexical-handler/parameter-entities</td>
- * <td>false (DOM doesn't do parameter entities)</td></tr>
- *
- * <tr><td colspan=2><center><em>Properties ... URL prefix is
- * <b>http://xml.org/sax/properties/</b></em></center></td></tr>
- *
- *
- * <tr><td>(URL)/dom-node</td>
- * <td>This property may be set before parsing to hold a DOM
- * <em>Document</em> node; any arguments given to <em>parse</em>
- * methods are ignored. When retrieved
- * during a parse, this value contains the "current" DOM node.
- * </td></tr>
- * <tr><td>(URL)/declaration-handler</td>
- * <td>A declaration handler may be provided. Declaration of external
- * general entities is exposed, but not parameter entities; none of the
- * entity names reported here will begin with "%". </td></tr>
- * <tr><td>(URL)/lexical-handler</td>
- * <td>A lexical handler may be provided. While the start and end of
- * any external subset are reported, expansion of other parameter
- * entities (e.g. inside attribute list declarations) is not exposed.
- * Expansion of general entities within attributes is also not exposed
- * (see below).</td></tr>
- * </table>
- *
- * <P> The consequences of modifying a DOM document tree as it is being walked
- * by this "parser" are unspecified; don't do it! </P>
- *
- * @author David Brownell
- */
- final public class DomParser implements XMLReader
- {
- // Stuff used internally to route events correctly
- private DefaultHandler2 defaultHandler = new DefaultHandler2 ();
- // per-parse SAX stuff
- private ContentHandler contentHandler = defaultHandler;
- private DTDHandler dtdHandler = defaultHandler;
- private DeclHandler declHandler = defaultHandler;
- private LexicalHandler lexicalHandler = defaultHandler;
- // shared context
- private ErrorHandler errHandler = defaultHandler;
- private EntityResolver resolver = defaultHandler;
- private Locale locale = Locale.getDefault ();
- // parser state
- private Node start;
- private Node current;
- private boolean isL2;
- private boolean showNamespaces = true;
- private boolean showXML1_0 = false;
- private NamespaceSupport prefixStack = new NamespaceSupport ();
- private boolean isDocument;
- /**
- * Constructs an unitialized <b>SAX2</b> parser.
- */
- public DomParser () {
- }
- /**
- * Constructs an <b>SAX2</b> parser initialized to traverse the specified
- * DOM tree. If the node is a document, the startDocument() and
- * endDocument() calls bracket the calls exposing children.
- */
- public DomParser (Node node) {
- setStart (node);
- }
- // stuff that most components in an application should be sharing:
- // resolver and error locale.
- /**
- * <b>SAX2</b>: Returns the object used when resolving external
- * entities during parsing (both general and parameter entities).
- */
- public EntityResolver getEntityResolver ()
- {
- return resolver;
- }
- /**
- * <b>SAX1</b>: Provides an object which may be used when resolving external
- * entities during parsing (both general and parameter entities).
- */
- public void setEntityResolver (EntityResolver resolver)
- {
- if (resolver == null)
- resolver = defaultHandler;
- this.resolver = resolver;
- }
- /**
- * <b>SAX1</b>: Identifies the locale which the parser should use for the
- * diagnostics it provides.
- *
- * @exception SAXException as defined in the specification for
- * <em>org.xml.sax.Parser.setLocale()</em>
- */
- public void setLocale (Locale locale)
- throws SAXException
- {
- if (locale == null)
- locale = Locale.getDefault ();
- this.locale = locale;
- }
- // different modules will tend to handle error handling the same,
- // but it may not be the same through the whole app
- /**
- * <b>SAX2</b>: Returns the object used to receive callbacks for XML
- * errors of all levels (fatal, nonfatal, warning).
- */
- public ErrorHandler getErrorHandler ()
- {
- return errHandler;
- }
- /**
- * <b>SAX1</b>: Provides an object which receives callbacks for XML errors
- * of all levels (fatal, nonfatal, warning).
- */
- public void setErrorHandler (ErrorHandler handler)
- {
- if (handler == null)
- handler = defaultHandler;
- errHandler = handler;
- }
- // stuff different parts of a module will handle differently
- /**
- * <b>SAX2</b>: Returns the object used to report the logical
- * content of an XML document.
- */
- public ContentHandler getContentHandler ()
- {
- return contentHandler;
- }
- /**
- * <b>SAX2</b>: Assigns the object used to report the logical
- * content of an XML document.
- */
- public void setContentHandler (ContentHandler handler)
- {
- if (handler == null)
- handler = defaultHandler;
- contentHandler = handler;
- }
- /**
- * <b>SAX2</b>: Returns the object used to process declarations related
- * to notations and unparsed entities.
- */
- public DTDHandler getDTDHandler ()
- {
- return dtdHandler;
- }
- /**
- * <b>SAX1</b>: Provides an object which may be used to intercept
- * declarations related to notations and unparsed entities.
- */
- public void setDTDHandler (DTDHandler handler)
- {
- if (handler == null)
- handler = defaultHandler;
- dtdHandler = handler;
- }
- /**
- * <b>SAX1</b>: Parses the previously provided DOM document (the
- * input parameter is ignored). When this returns, that same
- * document may be parsed again without needing a "reset".
- *
- * @param uri ignored (pass an empty string)
- * @exception SAXException as defined in the specification for
- * <em>org.xml.sax.Parser.parse()</em>
- */
- public void parse (String uri) throws SAXException
- {
- parse ();
- }
- /**
- * <b>SAX1</b>: Parses the previously provided DOM document (the
- * input parameter is ignored). When this returns, that same
- * document may be parsed again without needing a "reset".
- *
- * @param input ignored
- * @exception SAXException as defined in the specification for
- * <em>org.xml.sax.Parser.parse()</em>
- */
- public void parse (InputSource input) throws SAXException
- {
- parse ();
- }
- private void parse () throws SAXException
- {
- try {
- walk ();
- } finally {
- if (isDocument)
- contentHandler.endDocument ();
- current = null;
- prefixStack.reset ();
- }
- }
- private boolean getIsL2 (Node node)
- {
- DOMImplementation impl;
- Document doc;
- if (node instanceof Document)
- doc = (Document) node;
- else
- doc = node.getOwnerDocument ();
- if (doc == null)
- throw new RuntimeException ("? unowned node - L2 DTD ?");
- impl = doc.getImplementation ();
- return impl.hasFeature ("XML", "2.0");
- }
- private static final String FEATURES = "http://xml.org/sax/features/";
- private static final String HANDLERS = "http://xml.org/sax/properties/";
- /**
- * <b>SAX2</b>: Tells whether this parser supports the specified feature.
- */
- public boolean getFeature (String name)
- throws SAXNotRecognizedException, SAXNotSupportedException
- {
- // basically, none are relevant -- they relate more to
- // parsing than to walking a "parse tree".
- // FIXME: DOM feature to expose interning?
- if ((FEATURES + "validation").equals (name)
- || (FEATURES + "external-general-entities")
- .equals (name)
- || (FEATURES + "external-parameter-entities")
- .equals (name)
- || (FEATURES + "string-interning").equals (name)
- )
- return false;
- if ((FEATURES + "namespaces").equals (name))
- return showNamespaces;
- if ((FEATURES + "namespace-prefixes").equals (name))
- return showXML1_0;
- throw new SAXNotRecognizedException (name);
- }
- /**
- * <b>SAX2</b>: Returns the specified property. At this time only
- * the declaration and lexical handlers, and current the "DOM" node,
- * are supported.
- */
- public Object getProperty (String name)
- throws SAXNotRecognizedException, SAXNotSupportedException
- {
- if ((HANDLERS + "declaration-handler").equals (name))
- return declHandler == defaultHandler ? null : declHandler;
- if ((HANDLERS + "lexical-handler").equals (name))
- return lexicalHandler == defaultHandler ? null : lexicalHandler;
- if ((HANDLERS + "dom-node").equals (name))
- return current;
- // unknown properties
- throw new SAXNotRecognizedException (name);
- }
- /**
- * <b>SAX2</b>: Sets the state of features supported in this parser.
- * Only the namespace support features are mutable.
- */
- public void setFeature (String name, boolean state)
- throws SAXNotRecognizedException, SAXNotSupportedException
- {
- if (current != null)
- throw new IllegalStateException ("feature change midparse");
- boolean value = getFeature (name);
- if (value == state)
- return;
- if ((FEATURES + "namespaces").equals (name)) {
- if (!showXML1_0 && state == false)
- throw new SAXNotSupportedException ("Illegal namespace "
- + "processing configuration");
- showNamespaces = state;
- return;
- }
- if ((FEATURES + "namespace-prefixes").equals (name)) {
- if (!showNamespaces && state == false)
- throw new SAXNotSupportedException ("Illegal namespace "
- + "processing configuration");
- showXML1_0 = state;
- return;
- }
- throw new SAXNotSupportedException (name);
- }
- /**
- * <b>SAX2</b>: Assigns the specified property. At this time only
- * declaration and lexical handlers, and the initial DOM document, are
- * supported. These must not be changed to values of the wrong type.
- * Like SAX1 handlers, these handlers may be changed at any time.
- * Like SAX1 input source or document URI, the initial DOM document
- * may not be changed during a parse.
- */
- public void setProperty (String name, Object state)
- throws SAXNotRecognizedException, SAXNotSupportedException
- {
- if ((HANDLERS + "declaration-handler").equals (name)) {
- if (!(state instanceof DeclHandler || state == null))
- throw new SAXNotSupportedException (name);
- declHandler = (DeclHandler) state;
- return;
- }
- if ((HANDLERS + "lexical-handler").equals (name)) {
- if (!(state instanceof LexicalHandler || state == null))
- throw new SAXNotSupportedException (name);
- lexicalHandler = (LexicalHandler) state;
- return;
- }
- if ((HANDLERS + "dom-node").equals (name)) {
- if (state == null || state instanceof Node) {
- if (current != null)
- throw new SAXNotSupportedException (
- "property is readonly during parse: " + name);
- setStart ((Node) state);
- return;
- }
- throw new SAXNotSupportedException ("not a DOM Node");
- }
- // unknown properties
- throw new SAXNotRecognizedException (name);
- }
- private void setStart (Node property)
- {
- start = property;
- if (start != null) {
- isL2 = getIsL2 (start);
- isDocument = (start instanceof Document);
- }
- }
- //
- // Non-recursive walk, using DOM state when backtracking is needed
- //
- private void walk ()
- throws SAXException
- {
- int type;
- NamedNodeMap nodes;
- int length;
- AttributesImpl attrs = new AttributesImpl ();
- char chars [];
- String ns, local;
- synchronized (this) {
- if (current != null)
- throw new IllegalStateException ("already walking tree");
- // JVM guarantees assignments are atomic; so no other
- // thread could get this far till this walk's done.
- current = start;
- }
- for (;;) {
- type = current.getNodeType ();
- //
- // First, visit the current node, including any "start" calls
- //
- switch (type) {
- case Node.DOCUMENT_NODE:
- contentHandler.startDocument ();
- break;
- case Node.ELEMENT_NODE:
- nodes = current.getAttributes ();
- length = nodes.getLength ();
- prefixStack.pushContext ();
- for (int i = 0; i < length; i++) {
- Attr attr = (Attr) nodes.item (i);
- String name = attr.getNodeName ();
- if (showNamespaces && name.startsWith ("xmlns")) {
- String prefix;
- String uri;
- // NOTE: DOM L2 (CR2+ and REC) violate the
- // Namespaces REC, treat "xmlns" like a strange
- // attribute instead of a magic token
- if ("xmlns".equals (name))
- prefix = "";
- else
- prefix = name.substring (6);
- uri = attr.getNodeValue ();
- prefixStack.declarePrefix (prefix, uri);
- contentHandler.startPrefixMapping (prefix, uri);
- if (!showXML1_0)
- continue;
- }
- //
- // NOTE: DOM doesn't record the attribute type info
- // which SAX exposes; so this always reports CDATA.
- //
- // NOTE: SAX doesn't expose the isSpecified info which
- // DOM exposes; that's discarded here. Similarly with
- // the information DOM hides inside itself about what
- // the default values for an attribute are.
- //
- if (showNamespaces) {
- if (isL2) {
- if ((ns = attr.getNamespaceURI ()) == null)
- ns = "";
- // Note: SAX2 and DOM handle "local" names
- // differently
- if ((local = attr.getLocalName ()) == null)
- local = name;
- } else {
- // XXX
- throw new RuntimeException (
- "NYI, ns lookup when parsing L1 DOM");
- }
- } else
- ns = local = "";
- attrs.addAttribute (ns, local, name,
- "CDATA", attr.getNodeValue ());
- }
- if (showNamespaces) {
- if (isL2) {
- if ((ns = current.getNamespaceURI ()) == null)
- ns = "";
- // Note: SAX2 and DOM handle "local" names differently
- if ((local = current.getLocalName ()) == null)
- local = current.getNodeName ();
- } else {
- // XXX
- throw new RuntimeException (
- "NYI, ns lookup when parsing L1 DOM");
- }
- } else
- ns = local = "";
- contentHandler.startElement (ns, local,
- current.getNodeName (), attrs);
- if (length != 0)
- attrs.clear ();
- break;
- case Node.CDATA_SECTION_NODE:
- lexicalHandler.startCDATA ();
- chars = current.getNodeValue ().toCharArray ();
- contentHandler.characters (chars, 0, chars.length);
- lexicalHandler.endCDATA ();
- break;
- case Node.COMMENT_NODE:
- chars = current.getNodeValue ().toCharArray ();
- lexicalHandler.comment (chars, 0, chars.length);
- break;
- case Node.DOCUMENT_TYPE_NODE:
- {
- DocumentType doctype = (DocumentType) current;
- //
- // Only DOM L2 supports recreating even some DTDs in full.
- //
- if (isL2) {
- lexicalHandler.startDTD (doctype.getName (),
- doctype.getPublicId (),
- doctype.getSystemId ());
- } else
- lexicalHandler.startDTD (doctype.getName (),
- null, null);
- //
- // The only sure way to recreate is to provide both the
- // internal and external subsets. Otherwise, only part
- // of the job can be done ... because from the DTD, DOM
- // discards both the critical data, like the attribute and
- // element declarations, as well as the PIs and comments
- // that are used to hold their documentation.
- //
- // Even the entity and notation declarations that it can
- // expose can't be recorded without proprietary extensions.
- //
- // We construct a comment to tell what we know about how
- // (in)complete this particular really DTD is.
- //
- {
- String message;
- char buf [];
- //
- // Though DOM L2 lets the whole doctype be recreated,
- // SAX2 can't represent it (input or output).
- // So this will be the typical case.
- //
- if (isL2 && doctype.getInternalSubset () != null)
- message =
- " Full DTD known; can't be shown using SAX2. ";
- //
- // Otherwise, we'll concoct a partial DTD. If there's
- // any more data here at all, it was provided using a
- // (proprietary) extension to DOM.
- //
- else
- message =
- " This DTD was was recreated using incomplete DOM L2 records. ";
- buf = message.toCharArray ();
- lexicalHandler.comment (buf, 0, buf.length);
- }
- // report notations first
- nodes = doctype.getNotations ();
- length = nodes.getLength ();
- for (int i = 0; i < length; i++) {
- Notation notation = (Notation) nodes.item (i);
- dtdHandler.notationDecl (
- notation.getNodeName (),
- notation.getPublicId (),
- notation.getSystemId ());
- }
- // then parsed and unparsed external general entities
- nodes = doctype.getEntities ();
- length = nodes.getLength ();
- for (int i = 0; i < length; i++) {
- Entity entity = (Entity) nodes.item (i);
- String notation = entity.getNotationName ();
- if (notation != null)
- dtdHandler.unparsedEntityDecl (
- entity.getNodeName (),
- entity.getPublicId (),
- entity.getSystemId (),
- notation);
- else if (entity.getSystemId () != null)
- declHandler.externalEntityDecl (
- entity.getNodeName (),
- entity.getPublicId (),
- entity.getSystemId ());
- //
- // NOTE: DOM doesn't clearly provide internal
- // entity support; but in case someone tries to
- // fudge such support, we defend ourselves above.
- //
- // NOTE: DOM doesn't expose parameter entities
- // (thank you thank you thank you thank you)
- //
- }
- //
- // NOTE: DOM (levels 1 and 2) doesn't expose real
- // typing information (element or attribute decls),
- // as exposed by SAX2 declaration handlers.
- //
- lexicalHandler.endDTD ();
- }
- break;
- case Node.ENTITY_REFERENCE_NODE:
- // this isn't done except (a) in content, and
- // (b) not within a start tag (att value)
- lexicalHandler.startEntity (current.getNodeName ());
- break;
- case Node.PROCESSING_INSTRUCTION_NODE:
- contentHandler.processingInstruction (
- current.getNodeName (), current.getNodeValue ());
- break;
- case Node.TEXT_NODE:
- chars = current.getNodeValue ().toCharArray ();
- contentHandler.characters (chars, 0, chars.length);
- break;
- default:
- // e.g. fragments, entities, notations, attributes
- throw new SAXException ("Illegal DOM Node type in Document: "
- + current.getNodeType ());
- }
- //
- // Then, pick the next node to visit. If the next node isn't
- // a child, an "end" call may be needed before moving on.
- // If there's no next node, we're done.
- //
- Node next;
- switch (type) {
- case Node.DOCUMENT_NODE:
- case Node.ELEMENT_NODE:
- case Node.ENTITY_REFERENCE_NODE:
- //
- // For elements that can have children, visit those
- // children before any siblings (i.e. depth first)
- // and after visiting this node (i.e. preorder)
- //
- next = current.getFirstChild ();
- if (next != null) {
- current = next;
- break;
- }
- //
- // Else treat this like other childless nodes, but
- // handle this node's "end" immediately.
- //
- callEnd (current);
- // FALLTHROUGH
- case Node.CDATA_SECTION_NODE:
- case Node.COMMENT_NODE:
- case Node.DOCUMENT_TYPE_NODE:
- case Node.ENTITY_NODE:
- case Node.PROCESSING_INSTRUCTION_NODE:
- case Node.TEXT_NODE:
- //
- // Use next sibling, if there is one.
- // Else, climb up a level (calling "end")
- // until we find an ancestral sibling
- // or until we we climb off the top (FINISH)
- //
- for (;;) {
- if ((next = current.getNextSibling ()) != null)
- break;
- current = current.getParentNode ();
- if (current == null || current == start)
- return;
- callEnd (current);
- }
- current = next;
- break;
- default:
- throw new SAXException (
- "Illegal DOM Node type found: " + current.getNodeType ());
- }
- }
- }
- private void callEnd (Node node) throws SAXException
- {
- switch (node.getNodeType ()) {
- // only these three container types may ever be found
- // directly inside a Document.
- case Node.DOCUMENT_NODE:
- // for SAX conformance, endDocument must always
- // be called ... it's done in a "finally" clause)
- return;
- case Node.ELEMENT_NODE:
- if (showNamespaces) {
- if (isL2)
- contentHandler.endElement (
- node.getNamespaceURI (),
- node.getLocalName (),
- node.getNodeName ());
- else
- // XXX
- throw new RuntimeException (
- "NYI, ns lookup when parsing L1 DOM");
- for (Enumeration e = prefixStack.getDeclaredPrefixes ();
- e.hasMoreElements ();
- ) {
- contentHandler.endPrefixMapping ((String) e.nextElement ());
- }
- } else
- contentHandler.endElement ("", "", node.getNodeName ());
- prefixStack.popContext ();
- return;
- case Node.ENTITY_REFERENCE_NODE:
- // see above -- in content, outside start tags.
- lexicalHandler.endEntity (node.getNodeName ());
- return;
- // these can be given at the top level
- case Node.DOCUMENT_FRAGMENT_NODE:
- case Node.ATTRIBUTE_NODE:
- return;
- default:
- throw new SAXException (
- "Illegal DOM container type found: "
- + current.getNodeType ());
- }
- }
- }
|