net.sf.saxon.s9api.SchemaValidator Maven / Gradle / Ivy
Show all versions of saxon9 Show documentation
package net.sf.saxon.s9api;
import net.sf.saxon.Configuration;
import net.sf.saxon.event.PipelineConfiguration;
import net.sf.saxon.event.Receiver;
import net.sf.saxon.event.Sender;
import net.sf.saxon.event.Sink;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.om.Validation;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.SchemaType;
import net.sf.saxon.value.Whitespace;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
/**
* A SchemaValidator is an object that is used for validating instance documents against a schema.
* The schema consists of the collection of schema components that are available within the schema
* cache maintained by the SchemaManager, together with any additional schema components located
* during the course of validation by means of an xsl:schemaLocation or xsi:noNamespaceSchemaLocation
* attribute within the instance document.
*
* If validation fails, an exception is thrown. If validation succeeds, the validated document
* can optionally be written to a specified destination. This will be a copy of the original document,
* augmented with default values for absent elements and attributes, and carrying type annotations
* derived from the schema processing. Expansion of defaults can be suppressed by means of the method
* {@link #setExpandAttributeDefaults(boolean)}.
*
* A SchemaValidator is a Destination, which allows it to receive the output of a
* query or transformation to be validated.
*
* Saxon does not deliver the full PSVI as described in the XML schema specifications,
* only the subset of the PSVI properties featured in the XDM data model.
*
*/
public class SchemaValidator implements Destination {
private Configuration config;
private boolean lax;
private ErrorListener errorListener;
private Destination destination;
private QName documentElementName;
private SchemaType documentElementType;
private boolean expandAttributeDefaults = true;
protected SchemaValidator(Configuration config) {
this.config = config;
}
/**
* The validation mode may be either strict or lax. The default is strict; this method may be called
* to indicate that lax validation is required. With strict validation, validation fails if no element
* declaration can be located for the outermost element. With lax validation, the absence of an
* element declaration results in the content being considered valid.
* @param lax true if validation is to be lax, false if it is to be strict
*/
public void setLax(boolean lax) {
this.lax = lax;
}
/**
* Ask whether validation is to be in lax mode.
* @return true if validation is to be in lax mode, false if it is to be in strict mode.
*/
public boolean isLax() {
return lax;
}
/**
* Set the ErrorListener to be used while validating instance documents.
* @param listener The error listener to be used. This is notified of all errors detected during the
* validation episode.
*/
public void setErrorListener(ErrorListener listener) {
this.errorListener = listener;
}
/**
* Get the ErrorListener being used while validating instance documents
* @return listener The error listener in use. This is notified of all errors detected during the
* validation episode. Returns null if no user-supplied ErrorListener has been set.
*/
public ErrorListener getErrorListener() {
return errorListener;
}
/**
* Set the Destination to receive the validated document. If no destination is supplied, the
* validated document is discarded.
* @param destination the destination to receive the validated document
*/
public void setDestination(Destination destination) {
this.destination = destination;
}
/**
* Get the Destination that will receive the validated document. Return null if no destination
* has been set.
* @return the destination to receive the validated document, or null if none has been supplied
*/
public Destination getDestination() {
return destination;
}
/**
* Set the name of the required top-level element of the document to be validated (that is, the
* name of the outermost element of the document). If no value is supplied, there is no constraint
* on the required element name
* @param name the name of the document element, as a QName; or null to remove a previously-specified
* value.
*/
public void setDocumentElementName(QName name) {
documentElementName = name;
}
/**
* Get the name of the required top-level element of the document to be validated.
* @return the name of the required document element, or null if no value has been set.
*/
public QName getDocumentElementName() {
return documentElementName;
}
/**
* Set the name of the required type of the top-level element of the document to be validated.
* If no value is supplied, there is no constraint on the required type
* @param name the name of the type of the document element, as a QName;
* or null to remove a previously-specified value. This must be the name of a type in the
* schema (typically but not necessarily a complex type).
* @throws SaxonApiException if there is no known type with this name
*/
public void setDocumentElementTypeName(QName name) throws SaxonApiException {
int fp = config.getNamePool().allocate(
"", name.getNamespaceURI(), name.getLocalName());
documentElementType = config.getSchemaType(fp);
if (documentElementType == null) {
throw new SaxonApiException("Unknown type " + name.getClarkName());
}
}
/**
* Get the name of the required type of the top-level element of the document to be validated.
* @return the name of the required type of the document element, or null if no value has been set.
*/
public QName getDocumentElementTypeName() {
if (documentElementType == null) {
return null;
} else {
int fp = documentElementType.getFingerprint();
return new QName(new StructuredQName(config.getNamePool(), fp));
}
}
/**
* Get the schema type against which the document element is to be validated
* @return the schema type
*/
protected SchemaType getDocumentElementType() {
return documentElementType;
}
/**
* Set whether attribute defaults defined in a schema are to be expanded or not
* (by default, fixed and default attribute values are expanded, that is, they are inserted
* into the document during validation as if they were present in the instance being validated)
* @param expand true if defaults are to be expanded, false if not
*/
public void setExpandAttributeDefaults(boolean expand) {
expandAttributeDefaults = expand;
}
/**
* Ask whether attribute defaults defined in a schema are to be expanded or not
* (by default, fixed and default attribute values are expanded, that is, they are inserted
* into the document during validation as if they were present in the instance being validated)
* @return true if defaults are to be expanded, false if not
*/
public boolean isExpandAttributeDefaults() {
return expandAttributeDefaults;
}
/**
* Validate an instance document supplied as a Source object
* @param source the instance document to be validated. The call getSystemId() applied to
* this source object must return the base URI used for dereferencing any xsi:schemaLocation
* or xsi:noNamespaceSchemaLocation attributes
* @throws SaxonApiException if the source document is found to be invalid
*/
public void validate(Source source) throws SaxonApiException {
Receiver receiver = getReceiver(config, source.getSystemId());
PipelineConfiguration pipe = receiver.getPipelineConfiguration();
try {
new Sender(pipe).send(source, receiver, true);
} catch (XPathException e) {
throw new SaxonApiException(e);
}
}
public Receiver getReceiver(Configuration config) throws SaxonApiException {
return getReceiver(config, null);
}
private Receiver getReceiver(Configuration config, String systemId) throws SaxonApiException {
PipelineConfiguration pipe = config.makePipelineConfiguration();
pipe.setExpandAttributeDefaults(expandAttributeDefaults);
Receiver output = (destination == null ? new Sink() : destination.getReceiver(config));
output.setPipelineConfiguration(pipe);
int topLevelElement = -1;
if (documentElementName != null) {
topLevelElement = config.getNamePool().allocate(
"", documentElementName.getNamespaceURI(), documentElementName.getLocalName());
}
Receiver receiver = config.getDocumentValidator(
output,
systemId,
(lax ? Validation.LAX : Validation.STRICT) | Validation.VALIDATE_OUTPUT,
Whitespace.NONE,
documentElementType,
topLevelElement);
if (errorListener != null) {
pipe.setErrorListener(errorListener);
}
return receiver;
}
// public static void main(String[] args) {
//
// // This validation run should report exactly two validation errors.
//
// String source_xml = "ed sdsd a2009-01-01 b2009-01-01 ";
// String xsd = "\n" +
// "\t\n" +
// "\t\t\n" +
// "\t\t\t\n" +
// "\t\t\t\t\n" +
// "\t\t\t\t\n" +
// "\t\t\t\t\n" +
// "\t\t\t\t\n" +
// "\t\t\t \n" +
// "\t\t \n" +
// "\t \n" +
// " ";
//
// final List errorList = new ArrayList();
// try {
// Processor proc = new Processor(true);
// proc.setConfigurationProperty(net.sf.saxon.FeatureKeys.VALIDATION_WARNINGS, true);
// //proc.setConfigurationProperty(net.sf.saxon.FeatureKeys.SCHEMA_VALIDATION, Validation.LAX);
// SchemaManager sm = proc.getSchemaManager();
// StreamSource source_xsd = new StreamSource(new StringReader(xsd));
//
// ErrorListener listener = new ErrorListener() {
// public void error(TransformerException exception) throws TransformerException {
// errorList.add(exception);
// }
//
// public void fatalError(TransformerException exception) throws TransformerException {
// System.err.println("FATAL_ERROR:" + exception.getMessage());
// }
//
// public void warning(TransformerException exception) throws TransformerException {
// errorList.add(exception);
// }
// };
//
// SchemaValidator sv = sm.newSchemaValidator();
// sv.setErrorListener(listener);
// sm.load(source_xsd);
// StreamSource source = new StreamSource(new StringReader(source_xml));
// sv.validate(source);
//
// System.err.println("Validation errors not detected");
//
// }
//
// catch (SaxonApiException sapie) {
// System.err.println(errorList.size() == 2);
// }
// catch (Exception e) {
// System.err.println(e.getMessage());
// }
// }
}
//
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is: all this file
//
// The Initial Developer of the Original Code is Michael H. Kay.
//
// Contributor(s):
//