final Configuration config = pipe.getConfiguration();
ErrorListener listener = options.getErrorListener();
if (listener == null) {
listener = pipe.getErrorListener();
}
StandardErrorHandler standardErrorHandler = new StandardErrorHandler(listener);
if (parser==null) {
parser = options.getXMLReader();
}
if (parser==null) {
SAXSource ss = new SAXSource();
ss.setInputSource(source.getInputSource());
ss.setSystemId(source.getSystemId());
parser = config.getSourceParser();
parser.setErrorHandler(standardErrorHandler);
if (options.getEntityResolver() != null) {
parser.setEntityResolver(options.getEntityResolver());
}
ss.setXMLReader(parser);
source = ss;
reuseParser = true;
} else {
// user-supplied parser: ensure that it meets the namespace requirements
configureParser(parser);
if (parser.getErrorHandler() == null) {
parser.setErrorHandler(standardErrorHandler);
}
}
if (!pipe.isExpandAttributeDefaults()) { //TODO: put this in ParseOptions
try {
parser.setFeature("http://xml.org/sax/features/use-attributes2", true);
} catch (SAXNotRecognizedException err) {
// ignore the failure, we did our best (Xerces gives us an Attribute2 even though it
// doesn't recognize this request!)
} catch (SAXNotSupportedException err) {
// ignore the failure, we did our best
}
}
boolean dtdValidation = (options.getDTDValidationMode() == Validation.STRICT ||
options.getDTDValidationMode() == Validation.LAX);
boolean dtdRecover = options.getDTDValidationMode() == Validation.LAX;
try {
parser.setFeature("http://xml.org/sax/features/validation", dtdValidation);
} catch (SAXNotRecognizedException err) {
if (dtdValidation) {
throw new XPathException("XML Parser does not recognize request for DTD validation", err);
}
} catch (SAXNotSupportedException err) {
if (dtdValidation) {
throw new XPathException("XML Parser does not support DTD validation", err);
}
}
boolean xInclude = options.isXIncludeAware();
if (xInclude) {
boolean tryAgain = false;
try {
// This feature name is supported in the version of Xerces bundled with JDK 1.5
parser.setFeature("http://apache.org/xml/features/xinclude-aware", true);
} catch (SAXNotRecognizedException err) {
tryAgain = true;
} catch (SAXNotSupportedException err) {
tryAgain = true;
}
if (tryAgain) {
try {
// This feature name is supported in Xerces 2.9.0
parser.setFeature("http://apache.org/xml/features/xinclude", true);
} catch (SAXNotRecognizedException err) {
throw new XPathException("Selected XML parser " + parser.getClass().getName() +
" does not recognize request for XInclude processing", err);
} catch (SAXNotSupportedException err) {
throw new XPathException("Selected XML parser " + parser.getClass().getName() +
" does not support XInclude processing", err);
}
}
}
// if (config.isTiming()) {
// System.err.println("Using SAX parser " + parser);
// }
receiver = makeValidator(receiver, source.getSystemId(), options);
// Reuse the previous ReceivingContentHandler if possible (it contains a useful cache of names)
ReceivingContentHandler ce;
final ContentHandler ch = parser.getContentHandler();
if (ch instanceof ReceivingContentHandler) {
ce = (ReceivingContentHandler)ch;
ce.reset();
} else {
ce = new ReceivingContentHandler();
parser.setContentHandler(ce);
parser.setDTDHandler(ce);
try {
parser.setProperty("http://xml.org/sax/properties/lexical-handler", ce);
} catch (SAXNotSupportedException err) { // this just means we won't see the comments
// ignore the error
} catch (SAXNotRecognizedException err) {
// ignore the error
}
}
// TracingFilter tf = new TracingFilter();
// tf.setUnderlyingReceiver(receiver);
// tf.setPipelineConfiguration(pipe);
// receiver = tf;
ce.setReceiver(receiver);
ce.setPipelineConfiguration(pipe);
try {
parser.parse(source.getInputSource());
} catch (SAXException err) {
Exception nested = err.getException();
if (nested instanceof XPathException) {
throw (XPathException)nested;
} else if (nested instanceof RuntimeException) {
throw (RuntimeException)nested;
} else {
if (standardErrorHandler != null && standardErrorHandler.getFatalErrorCount() == 0) {
// The built-in parser for JDK 1.6 has a nasty habit of not notifying errors to the ErrorHandler
XPathException de = new XPathException("Error reported by XML parser processing " +
source.getSystemId() + ": " + err.getMessage(), err);
try {
options.getErrorListener().fatalError(de);
de.setHasBeenReported(true);
} catch (TransformerException e) {
//
}
throw de;
} else {
XPathException de = new XPathException(err);
de.setHasBeenReported(true);
throw de;
}
}
} catch (java.io.IOException err) {
throw new XPathException(err);
}
if (standardErrorHandler != null) {
int errs = standardErrorHandler.getFatalErrorCount();
if (errs > 0) {
throw new XPathException("The XML parser reported " + errs + (errs == 1 ? " error" : " errors"));
}
errs = standardErrorHandler.getErrorCount();
if (errs > 0) {
XPathException xe = new XPathException("The XML parser reported " + errs + " validation error" +
(errs == 1 ? "" : "s"));
if (dtdRecover) {
try {