The actual SAX parser that is used by this class is configurable so you can
use your favourite SAX parser if you wish. DOM4J comes configured with its
own SAX parser so you do not need to worry about configuring the SAX parser.
If the parser is not specified explicitly then the standard SAX policy of
using the org.xml.sax.driver system property is used to
determine the implementation class of XMLReader .
If you are trying to use JAXP to explicitly set your SAX parser and are
experiencing problems, you can turn on verbose error reporting by defining
the system property org.dom4j.verbose to be "true" which will
output a more detailed description of why JAXP could not find a SAX parser
| Method from org.dom4j.io.SAXReader Detail: |
public void addHandler(String path,
ElementHandler handler) {
getDispatchHandler().addHandler(path, handler);
}
Adds the ElementHandler to be called when the specified
path is encounted. |
protected void configureReader(XMLReader reader,
DefaultHandler handler) throws DocumentException {
// configure lexical handling
SAXHelper.setParserProperty(reader, SAX_LEXICALHANDLER, handler);
// try alternate property just in case
SAXHelper.setParserProperty(reader, SAX_LEXICAL_HANDLER, handler);
// register the DeclHandler
if (includeInternalDTDDeclarations || includeExternalDTDDeclarations) {
SAXHelper.setParserProperty(reader, SAX_DECL_HANDLER, handler);
}
// configure namespace support
SAXHelper.setParserFeature(reader, SAX_NAMESPACES, true);
SAXHelper.setParserFeature(reader, SAX_NAMESPACE_PREFIXES, false);
// string interning
SAXHelper.setParserFeature(reader, SAX_STRING_INTERNING,
isStringInternEnabled());
// external entites
/*
* SAXHelper.setParserFeature( reader,
* "http://xml.org/sax/properties/external-general-entities",
* includeExternalGeneralEntities ); SAXHelper.setParserFeature( reader,
* "http://xml.org/sax/properties/external-parameter-entities",
* includeExternalParameterEntities );
*/
// use Locator2 if possible
SAXHelper.setParserFeature(reader,
"http://xml.org/sax/features/use-locator2", true);
try {
// configure validation support
reader.setFeature("http://xml.org/sax/features/validation",
isValidating());
if (errorHandler != null) {
reader.setErrorHandler(errorHandler);
} else {
reader.setErrorHandler(handler);
}
} catch (Exception e) {
if (isValidating()) {
throw new DocumentException("Validation not supported for"
+ " XMLReader: " + reader, e);
}
}
}
Configures the XMLReader before use |
protected SAXContentHandler createContentHandler(XMLReader reader) {
return new SAXContentHandler(getDocumentFactory(), dispatchHandler);
}
Factory Method to allow user derived SAXContentHandler objects to be used |
protected EntityResolver createDefaultEntityResolver(String systemId) {
String prefix = null;
if ((systemId != null) && (systemId.length() > 0)) {
int idx = systemId.lastIndexOf('/");
if (idx > 0) {
prefix = systemId.substring(0, idx + 1);
}
}
return new SAXEntityResolver(prefix);
}
|
protected XMLReader createXMLReader() throws SAXException {
return SAXHelper.createXMLReader(isValidating());
}
Factory Method to allow alternate methods of creating and configuring
XMLReader objects |
protected DispatchHandler getDispatchHandler() {
if (dispatchHandler == null) {
dispatchHandler = new DispatchHandler();
}
return dispatchHandler;
}
|
public DocumentFactory getDocumentFactory() {
if (factory == null) {
factory = DocumentFactory.getInstance();
}
return factory;
}
|
public String getEncoding() {
return encoding;
}
Returns encoding used for InputSource (null means system default
encoding) |
public EntityResolver getEntityResolver() {
return entityResolver;
}
Returns the current entity resolver used to resolve entities |
public ErrorHandler getErrorHandler() {
return errorHandler;
}
|
public XMLFilter getXMLFilter() {
return xmlFilter;
}
Returns the SAX filter being used to filter SAX events. |
public XMLReader getXMLReader() throws SAXException {
if (xmlReader == null) {
xmlReader = createXMLReader();
}
return xmlReader;
}
|
protected XMLReader installXMLFilter(XMLReader reader) {
XMLFilter filter = getXMLFilter();
if (filter != null) {
// find the root XMLFilter
XMLFilter root = filter;
while (true) {
XMLReader parent = root.getParent();
if (parent instanceof XMLFilter) {
root = (XMLFilter) parent;
} else {
break;
}
}
root.setParent(reader);
return filter;
}
return reader;
}
Installs any XMLFilter objects required to allow the SAX event stream to
be filtered and preprocessed before it gets to dom4j. |
public boolean isIgnoreComments() {
return ignoreComments;
}
Returns whether we should ignore comments or not. |
public boolean isIncludeExternalDTDDeclarations() {
return includeExternalDTDDeclarations;
}
|
public boolean isIncludeInternalDTDDeclarations() {
return includeInternalDTDDeclarations;
}
|
public boolean isMergeAdjacentText() {
return mergeAdjacentText;
}
Returns whether adjacent text nodes should be merged together. |
public boolean isStringInternEnabled() {
return stringInternEnabled;
}
Sets whether String interning is enabled or disabled for element &
attribute names and namespace URIs. This proprety is enabled by default. |
public boolean isStripWhitespaceText() {
return stripWhitespaceText;
}
Sets whether whitespace between element start and end tags should be
ignored |
public boolean isValidating() {
return validating;
}
|
public Document read(File file) throws DocumentException {
try {
/*
* We cannot convert the file to an URL because if the filename
* contains '#' characters, there will be problems with the URL in
* the InputSource (because a URL like
* http://myhost.com/index#anchor is treated the same as
* http://myhost.com/index) Thanks to Christian Oetterli
*/
InputSource source = new InputSource(new FileInputStream(file));
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
String path = file.getAbsolutePath();
if (path != null) {
// Code taken from Ant FileUtils
StringBuffer sb = new StringBuffer("file://");
// add an extra slash for filesystems with drive-specifiers
if (!path.startsWith(File.separator)) {
sb.append("/");
}
path = path.replace('\\", '/");
sb.append(path);
source.setSystemId(sb.toString());
}
return read(source);
} catch (FileNotFoundException e) {
throw new DocumentException(e.getMessage(), e);
}
}
|
public Document read(URL url) throws DocumentException {
String systemID = url.toExternalForm();
InputSource source = new InputSource(systemID);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
|
public Document read(String systemId) throws DocumentException {
InputSource source = new InputSource(systemId);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
Reads a Document from the given URL or filename using SAX.
If the systemId contains a ':' character then it is
assumed to be a URL otherwise its assumed to be a file name. If you want
finer grained control over this mechansim then please explicitly pass in
either a URL or a File instance instead of a String to denote the source of the document.
|
public Document read(InputStream in) throws DocumentException {
InputSource source = new InputSource(in);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
|
public Document read(Reader reader) throws DocumentException {
InputSource source = new InputSource(reader);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
|
public Document read(InputSource in) throws DocumentException {
try {
XMLReader reader = getXMLReader();
reader = installXMLFilter(reader);
EntityResolver thatEntityResolver = this.entityResolver;
if (thatEntityResolver == null) {
thatEntityResolver = createDefaultEntityResolver(in
.getSystemId());
this.entityResolver = thatEntityResolver;
}
reader.setEntityResolver(thatEntityResolver);
SAXContentHandler contentHandler = createContentHandler(reader);
contentHandler.setEntityResolver(thatEntityResolver);
contentHandler.setInputSource(in);
boolean internal = isIncludeInternalDTDDeclarations();
boolean external = isIncludeExternalDTDDeclarations();
contentHandler.setIncludeInternalDTDDeclarations(internal);
contentHandler.setIncludeExternalDTDDeclarations(external);
contentHandler.setMergeAdjacentText(isMergeAdjacentText());
contentHandler.setStripWhitespaceText(isStripWhitespaceText());
contentHandler.setIgnoreComments(isIgnoreComments());
reader.setContentHandler(contentHandler);
configureReader(reader, contentHandler);
reader.parse(in);
return contentHandler.getDocument();
} catch (Exception e) {
if (e instanceof SAXParseException) {
// e.printStackTrace();
SAXParseException parseException = (SAXParseException) e;
String systemId = parseException.getSystemId();
if (systemId == null) {
systemId = "";
}
String message = "Error on line "
+ parseException.getLineNumber() + " of document "
+ systemId + " : " + parseException.getMessage();
throw new DocumentException(message, e);
} else {
throw new DocumentException(e.getMessage(), e);
}
}
}
|
public Document read(InputStream in,
String systemId) throws DocumentException {
InputSource source = new InputSource(in);
source.setSystemId(systemId);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
|
public Document read(Reader reader,
String systemId) throws DocumentException {
InputSource source = new InputSource(reader);
source.setSystemId(systemId);
if (this.encoding != null) {
source.setEncoding(this.encoding);
}
return read(source);
}
|
public void removeHandler(String path) {
getDispatchHandler().removeHandler(path);
}
Removes the ElementHandler from the event based processor,
for the specified path. |
public void resetHandlers() {
getDispatchHandler().resetHandlers();
}
This method clears out all the existing handlers and default handler
setting things back as if no handler existed. Useful when reusing an
object instance. |
public void setDefaultHandler(ElementHandler handler) {
getDispatchHandler().setDefaultHandler(handler);
}
When multiple ElementHandler instances have been
registered, this will set a default ElementHandler to be
called for any path which does NOT have a handler registered. |
protected void setDispatchHandler(DispatchHandler dispatchHandler) {
this.dispatchHandler = dispatchHandler;
}
|
public void setDocumentFactory(DocumentFactory documentFactory) {
this.factory = documentFactory;
}
This sets the DocumentFactory used to create new
documents. This method allows the building of custom DOM4J tree objects
to be implemented easily using a custom derivation of
DocumentFactory
|
public void setEncoding(String encoding) {
this.encoding = encoding;
}
Sets encoding used for InputSource (null means system default encoding) |
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
Sets the entity resolver used to resolve entities. |
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
Sets the ErrorHandler used by the SAX
XMLReader. |
public void setFeature(String name,
boolean value) throws SAXException {
getXMLReader().setFeature(name, value);
}
Sets a SAX feature on the underlying SAX parser. This can be useful to
set parser-specific features. Though use this method with caution as it
has the possibility of breaking the standard behaviour. An alternative to
calling this method is to correctly configure an XMLReader object
instance and call the #setXMLReader(XMLReader) method |
public void setIgnoreComments(boolean ignoreComments) {
this.ignoreComments = ignoreComments;
}
Sets whether we should ignore comments or not. |
public void setIncludeExternalDTDDeclarations(boolean include) {
this.includeExternalDTDDeclarations = include;
}
Sets whether DTD external declarations should be expanded into the
DocumentType object or not. |
public void setIncludeInternalDTDDeclarations(boolean include) {
this.includeInternalDTDDeclarations = include;
}
Sets whether internal DTD declarations should be expanded into the
DocumentType object or not. |
public void setMergeAdjacentText(boolean mergeAdjacentText) {
this.mergeAdjacentText = mergeAdjacentText;
}
Sets whether or not adjacent text nodes should be merged together when
parsing. |
public void setProperty(String name,
Object value) throws SAXException {
getXMLReader().setProperty(name, value);
}
Allows a SAX property to be set on the underlying SAX parser. This can be
useful to set parser-specific properties such as the location of schema
or DTD resources. Though use this method with caution as it has the
possibility of breaking the standard behaviour. An alternative to calling
this method is to correctly configure an XMLReader object instance and
call the #setXMLReader(XMLReader) method |
public void setStringInternEnabled(boolean stringInternEnabled) {
this.stringInternEnabled = stringInternEnabled;
}
Sets whether String interning is enabled or disabled for element &
attribute names and namespace URIs |
public void setStripWhitespaceText(boolean stripWhitespaceText) {
this.stripWhitespaceText = stripWhitespaceText;
}
Sets whether whitespace between element start and end tags should be
ignored. |
public void setValidation(boolean validation) {
this.validating = validation;
}
Sets the validation mode. |
public void setXMLFilter(XMLFilter filter) {
this.xmlFilter = filter;
}
Sets the SAX filter to be used when filtering SAX events |
public void setXMLReader(XMLReader reader) {
this.xmlReader = reader;
}
Sets the XMLReader used to parse SAX events |
public void setXMLReaderClassName(String xmlReaderClassName) throws SAXException {
setXMLReader(XMLReaderFactory.createXMLReader(xmlReaderClassName));
}
Sets the class name of the XMLReader to be used to parse
SAX events. |