📄 saxbuilder.java
字号:
* Specifies whether or not the parser should elminate boundary whitespace,
* a term that indicates whitespace-only text between element tags. This
* feature is a lot like {@link #setIgnoringElementContentWhitespace(boolean)}
* but this feature is more aggressive and doesn't require validation be
* turned on. The {@link #setIgnoringElementContentWhitespace(boolean)}
* call impacts the SAX parse process while this method impacts the JDOM
* build process, so it can be beneficial to turn both on for efficiency.
* For implementation efficiency, this method actually removes all
* whitespace-only text() nodes. That can, in some cases (like beteween an
* element tag and a comment), include whitespace that isn't just boundary
* whitespace. The default is <code>false</code>.
*
* @param ignoringBoundaryWhite Whether to ignore whitespace-only text
* noes
*/
public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) {
this.ignoringBoundaryWhite = ignoringBoundaryWhite;
}
/**
* Returns whether the contained SAX parser instance is reused across
* multiple parses. The default is true.
*
* @return whether the contained SAX parser instance is reused across
* multiple parses
*/
public boolean getReuseParser() {
return reuseParser;
}
/**
* Specifies whether this builder shall reuse the same SAX parser
* when performing subsequent parses or allocate a new parser for
* each parse. The default value of this setting is
* <code>true</code> (parser reuse).
* <p>
* <strong>Note</strong>: As SAX parser instances are not thread safe,
* the parser reuse feature should not be used with SAXBuilder instances
* shared among threads.</p>
*
* @param reuseParser Whether to reuse the SAX parser.
*/
public void setReuseParser(boolean reuseParser) {
this.reuseParser = reuseParser;
this.saxParser = null;
}
/**
* This sets a feature on the SAX parser. See the SAX documentation for
* </p>
* <p>
* NOTE: SAXBuilder requires that some particular features of the SAX parser be
* set up in certain ways for it to work properly. The list of such features
* may change in the future. Therefore, the use of this method may cause
* parsing to break, and even if it doesn't break anything today it might
* break parsing in a future JDOM version, because what JDOM parsers require
* may change over time. Use with caution.
* </p>
*
* @param name The feature name, which is a fully-qualified URI.
* @param value The requested state of the feature (true or false).
*/
public void setFeature(String name, boolean value) {
// Save the specified feature for later.
features.put(name, new Boolean(value));
}
/**
* This sets a property on the SAX parser. See the SAX documentation for
* more information.
* <p>
* NOTE: SAXBuilder requires that some particular properties of the SAX parser be
* set up in certain ways for it to work properly. The list of such properties
* may change in the future. Therefore, the use of this method may cause
* parsing to break, and even if it doesn't break anything today it might
* break parsing in a future JDOM version, because what JDOM parsers require
* may change over time. Use with caution.
* </p>
*
* @param name The property name, which is a fully-qualified URI.
* @param value The requested value for the property.
*/
public void setProperty(String name, Object value) {
// Save the specified property for later.
properties.put(name, value);
}
/**
* This builds a document from the supplied
* input source.
*
* @param in <code>InputSource</code> to read from
* @return <code>Document</code> resultant Document object
* @throws JDOMException when errors occur in parsing
* @throws IOException when an I/O error prevents a document
* from being fully parsed
*/
public Document build(InputSource in)
throws JDOMException, IOException {
SAXHandler contentHandler = null;
try {
// Create and configure the content handler.
contentHandler = createContentHandler();
configureContentHandler(contentHandler);
XMLReader parser = this.saxParser;
if (parser == null) {
// Create and configure the parser.
parser = createParser();
// Install optional filter
if (saxXMLFilter != null) {
// Connect filter chain to parser
XMLFilter root = saxXMLFilter;
while (root.getParent() instanceof XMLFilter) {
root = (XMLFilter)root.getParent();
}
root.setParent(parser);
// Read from filter
parser = saxXMLFilter;
}
// Configure parser
configureParser(parser, contentHandler);
if (reuseParser == true) {
this.saxParser = parser;
}
}
else {
// Reset content handler as SAXHandler instances cannot
// be reused
configureParser(parser, contentHandler);
}
// Parse the document.
parser.parse(in);
return contentHandler.getDocument();
}
catch (SAXParseException e) {
Document doc = contentHandler.getDocument();
if (doc.hasRootElement() == false) {
doc = null;
}
String systemId = e.getSystemId();
if (systemId != null) {
throw new JDOMParseException("Error on line " +
e.getLineNumber() + " of document " + systemId, e, doc);
} else {
throw new JDOMParseException("Error on line " +
e.getLineNumber(), e, doc);
}
}
catch (SAXException e) {
throw new JDOMParseException("Error in building: " +
e.getMessage(), e, contentHandler.getDocument());
}
finally {
// Explicitly nullify the handler to encourage GC
// It's a stack var so this shouldn't be necessary, but it
// seems to help on some JVMs
contentHandler = null;
}
}
/**
* This creates the SAXHandler that will be used to build the Document.
*
* @return <code>SAXHandler</code> - resultant SAXHandler object.
*/
protected SAXHandler createContentHandler() {
SAXHandler contentHandler = new SAXHandler(factory);
return contentHandler;
}
/**
* This configures the SAXHandler that will be used to build the Document.
* <p>
* The default implementation simply passes through some configuration
* settings that were set on the SAXBuilder: setExpandEntities() and
* setIgnoringElementContentWhitespace().
* </p>
*/
protected void configureContentHandler(SAXHandler contentHandler) {
// Setup pass through behavior
contentHandler.setExpandEntities(expand);
contentHandler.setIgnoringElementContentWhitespace(ignoringWhite);
contentHandler.setIgnoringBoundaryWhitespace(ignoringBoundaryWhite);
}
/**
* This creates the XMLReader to be used for reading the XML document.
* <p>
* The default behavior is to (1) use the saxDriverClass, if it has been
* set, (2) try to obtain a parser from JAXP, if it is available, and
* (3) if all else fails, use a hard-coded default parser (currently
* the Xerces parser). Subclasses may override this method to determine
* the parser to use in a different way.
* </p>
*
* @return <code>XMLReader</code> - resultant XMLReader object.
*/
protected XMLReader createParser() throws JDOMException {
XMLReader parser = null;
if (saxDriverClass != null) {
// The user knows that they want to use a particular class
try {
parser = XMLReaderFactory.createXMLReader(saxDriverClass);
// Configure parser
setFeaturesAndProperties(parser, true);
}
catch (SAXException e) {
throw new JDOMException("Could not load " + saxDriverClass, e);
}
} else {
// Try using JAXP...
// Note we need JAXP 1.1, and if JAXP 1.0 is all that's
// available then the getXMLReader call fails and we skip
// to the hard coded default parser
try {
// Get factory class and method.
Class factoryClass =
Class.forName("org.jdom.input.JAXPParserFactory");
Method createParser =
factoryClass.getMethod("createParser",
new Class[] { boolean.class, Map.class, Map.class });
// Create SAX parser.
parser = (XMLReader)createParser.invoke(null,
new Object[] { new Boolean(validate),
features, properties });
// Configure parser
setFeaturesAndProperties(parser, false);
}
catch (JDOMException e) {
throw e;
}
catch (NoClassDefFoundError e) {
// The class loader failed to resolve the dependencies
// of org.jdom.input.JAXPParserFactory. This probably means
// that no JAXP parser is present in its class path.
// => Ignore and try allocating default SAX parser instance.
}
catch (Exception e) {
// Ignore and try allocating default SAX parser instance.
}
}
// Check to see if we got a parser yet, if not, try to use a
// hard coded default
if (parser == null) {
try {
parser = XMLReaderFactory.createXMLReader(DEFAULT_SAX_DRIVER);
// System.out.println("using default " + DEFAULT_SAX_DRIVER);
saxDriverClass = parser.getClass().getName();
// Configure parser
setFeaturesAndProperties(parser, true);
}
catch (SAXException e) {
throw new JDOMException("Could not load default SAX parser: "
+ DEFAULT_SAX_DRIVER, e);
}
}
return parser;
}
/**
* This configures the XMLReader to be used for reading the XML document.
* <p>
* The default implementation sets various options on the given XMLReader,
* such as validation, DTD resolution, entity handlers, etc., according
* to the options that were set (e.g. via <code>setEntityResolver</code>)
* and set various SAX properties and features that are required for JDOM
* internals. These features may change in future releases, so change this
* behavior at your own risk.
* </p>
*/
protected void configureParser(XMLReader parser, SAXHandler contentHandler)
throws JDOMException {
// Setup SAX handlers.
parser.setContentHandler(contentHandler);
if (saxEntityResolver != null) {
parser.setEntityResolver(saxEntityResolver);
}
if (saxDTDHandler != null) {
parser.setDTDHandler(saxDTDHandler);
} else {
parser.setDTDHandler(contentHandler);
}
if (saxErrorHandler != null) {
parser.setErrorHandler(saxErrorHandler);
} else {
parser.setErrorHandler(new BuilderErrorHandler());
}
// Setup lexical reporting.
boolean lexicalReporting = false;
try {
parser.setProperty("http://xml.org/sax/handlers/LexicalHandler",
contentHandler);
lexicalReporting = true;
} catch (SAXNotSupportedException e) {
// No lexical reporting available
} catch (SAXNotRecognizedException e) {
// No lexical reporting available
}
// Some parsers use alternate property for lexical handling (grr...)
if (!lexicalReporting) {
try {
parser.setProperty(
"http://xml.org/sax/properties/lexical-handler",
contentHandler);
lexicalReporting = true;
} catch (SAXNotSupportedException e) {
// No lexical reporting available
} catch (SAXNotRecognizedException e) {
// No lexical reporting available
}
}
// Try setting the DeclHandler if entity expansion is off
if (!expand) {
try {
parser.setProperty(
"http://xml.org/sax/properties/declaration-handler",
contentHandler);
} catch (SAXNotSupportedException e) {
// No lexical reporting available
} catch (SAXNotRecognizedException e) {
// No lexical reporting available
}
}
}
private void setFeaturesAndProperties(XMLReader parser,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -