📄 saxcontenthandler.java
字号:
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
package org.dom4j.io;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Branch;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentType;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.dtd.AttributeDecl;
import org.dom4j.dtd.ElementDecl;
import org.dom4j.dtd.ExternalEntityDecl;
import org.dom4j.dtd.InternalEntityDecl;
import org.dom4j.tree.AbstractElement;
import org.dom4j.tree.NamespaceStack;
import org.xml.sax.Attributes;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
/**
* <p>
* <code>SAXContentHandler</code> builds a dom4j tree via SAX events.
* </p>
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
* @version $Revision: 1.61 $
*/
public class SAXContentHandler extends DefaultHandler implements
LexicalHandler, DeclHandler, DTDHandler {
/** The factory used to create new <code>Document</code> instances */
private DocumentFactory documentFactory;
/** The document that is being built */
private Document document;
/** stack of <code>Element</code> objects */
private ElementStack elementStack;
/** stack of <code>Namespace</code> and <code>QName</code> objects */
private NamespaceStack namespaceStack;
/** the <code>ElementHandler</code> called as the elements are complete */
private ElementHandler elementHandler;
/** the Locator */
private Locator locator;
/** The name of the current entity */
private String entity;
/** Flag used to indicate that we are inside a DTD section */
private boolean insideDTDSection;
/** Flag used to indicate that we are inside a CDATA section */
private boolean insideCDATASection;
/**
* buffer to hold contents of cdata section across multiple characters
* events
*/
private StringBuffer cdataText;
/** namespaces that are available for use */
private Map availableNamespaceMap = new HashMap();
/** declared namespaces that are not yet available for use */
private List declaredNamespaceList = new ArrayList();
/** internal DTD declarations */
private List internalDTDDeclarations;
/** external DTD declarations */
private List externalDTDDeclarations;
/** The number of namespaces that are declared in the current scope */
private int declaredNamespaceIndex;
/** The entity resolver */
private EntityResolver entityResolver;
private InputSource inputSource;
/** The current element we are on */
private Element currentElement;
/** Should internal DTD declarations be expanded into a List in the DTD */
private boolean includeInternalDTDDeclarations = false;
/** Should external DTD declarations be expanded into a List in the DTD */
private boolean includeExternalDTDDeclarations = false;
/** The number of levels deep we are inside a startEntity/endEntity call */
private int entityLevel;
/** Are we in an internal DTD subset? */
private boolean internalDTDsubset = false;
/** Whether adjacent text nodes should be merged */
private boolean mergeAdjacentText = false;
/** Have we added text to the buffer */
private boolean textInTextBuffer = false;
/** Should we ignore comments */
private boolean ignoreComments = false;
/** Buffer used to concatenate text together */
private StringBuffer textBuffer;
/** Holds value of property stripWhitespaceText. */
private boolean stripWhitespaceText = false;
public SAXContentHandler() {
this(DocumentFactory.getInstance());
}
public SAXContentHandler(DocumentFactory documentFactory) {
this(documentFactory, null);
}
public SAXContentHandler(DocumentFactory documentFactory,
ElementHandler elementHandler) {
this(documentFactory, elementHandler, null);
this.elementStack = createElementStack();
}
public SAXContentHandler(DocumentFactory documentFactory,
ElementHandler elementHandler, ElementStack elementStack) {
this.documentFactory = documentFactory;
this.elementHandler = elementHandler;
this.elementStack = elementStack;
this.namespaceStack = new NamespaceStack(documentFactory);
}
/**
* DOCUMENT ME!
*
* @return the document that has been or is being built
*/
public Document getDocument() {
if (document == null) {
document = createDocument();
}
return document;
}
// ContentHandler interface
// -------------------------------------------------------------------------
public void setDocumentLocator(Locator documentLocator) {
this.locator = documentLocator;
}
public void processingInstruction(String target, String data)
throws SAXException {
if (mergeAdjacentText && textInTextBuffer) {
completeCurrentTextNode();
}
if (currentElement != null) {
currentElement.addProcessingInstruction(target, data);
} else {
getDocument().addProcessingInstruction(target, data);
}
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
namespaceStack.push(prefix, uri);
}
public void endPrefixMapping(String prefix) throws SAXException {
namespaceStack.pop(prefix);
declaredNamespaceIndex = namespaceStack.size();
}
public void startDocument() throws SAXException {
// document = createDocument();
document = null;
currentElement = null;
elementStack.clear();
if ((elementHandler != null)
&& (elementHandler instanceof DispatchHandler)) {
elementStack.setDispatchHandler((DispatchHandler) elementHandler);
}
namespaceStack.clear();
declaredNamespaceIndex = 0;
if (mergeAdjacentText && (textBuffer == null)) {
textBuffer = new StringBuffer();
}
textInTextBuffer = false;
}
public void endDocument() throws SAXException {
namespaceStack.clear();
elementStack.clear();
currentElement = null;
textBuffer = null;
}
public void startElement(String namespaceURI, String localName,
String qualifiedName, Attributes attributes) throws SAXException {
if (mergeAdjacentText && textInTextBuffer) {
completeCurrentTextNode();
}
QName qName = namespaceStack.getQName(namespaceURI, localName,
qualifiedName);
Branch branch = currentElement;
if (branch == null) {
branch = getDocument();
}
Element element = branch.addElement(qName);
// add all declared namespaces
addDeclaredNamespaces(element);
// now lets add all attribute values
addAttributes(element, attributes);
elementStack.pushElement(element);
currentElement = element;
entity = null; // fixes bug527062
if (elementHandler != null) {
elementHandler.onStart(elementStack);
}
}
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (mergeAdjacentText && textInTextBuffer) {
completeCurrentTextNode();
}
if ((elementHandler != null) && (currentElement != null)) {
elementHandler.onEnd(elementStack);
}
elementStack.popElement();
currentElement = elementStack.peekElement();
}
public void characters(char[] ch, int start, int end) throws SAXException {
if (end == 0) {
return;
}
if (currentElement != null) {
if (entity != null) {
if (mergeAdjacentText && textInTextBuffer) {
completeCurrentTextNode();
}
currentElement.addEntity(entity, new String(ch, start, end));
entity = null;
} else if (insideCDATASection) {
if (mergeAdjacentText && textInTextBuffer) {
completeCurrentTextNode();
}
cdataText.append(new String(ch, start, end));
} else {
if (mergeAdjacentText) {
textBuffer.append(ch, start, end);
textInTextBuffer = true;
} else {
currentElement.addText(new String(ch, start, end));
}
}
}
}
// ErrorHandler interface
// -------------------------------------------------------------------------
/**
* This method is called when a warning occurs during the parsing of the
* document. This method does nothing.
*
* @param exception
* DOCUMENT ME!
*
* @throws SAXException
* DOCUMENT ME!
*/
public void warning(SAXParseException exception) throws SAXException {
// ignore warnings by default
}
/**
* This method is called when an error is detected during parsing such as a
* validation error. This method rethrows the exception
*
* @param exception
* DOCUMENT ME!
*
* @throws SAXException
* DOCUMENT ME!
*/
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -