aSaxon-B-9-0-0-8sources.api.Saxon.Api.Schema.cs Maven / Gradle / Ivy
The newest version!
using System;
using System.IO;
using System.Xml;
using System.Collections;
using javax.xml.transform;
using javax.xml.transform.stream;
//using JConfiguration = com.saxonica.validate.SchemaAwareConfiguration;
using JConfiguration = net.sf.saxon.Configuration;
using JReceiver = [email protected];
using net.sf.saxon;
using net.sf.saxon.om;
using net.sf.saxon.pull;
using net.sf.saxon.@event;
using net.sf.saxon.dotnet;
using net.sf.saxon.type;
namespace Saxon.Api {
///
/// A SchemaManager is responsible for compiling schemas and
/// maintaining a cache of compiled schemas that can be used for validating
/// instance documents.
///
///
/// To obtain a SchemaManager , use the
/// SchemaManager property of the Processor object.
/// In a schema-aware Processor there is exactly one
/// SchemaManager (in a non-schema-aware Processor there is none).
/// The cache of compiled schema definitions can include only one schema
/// component (for example a type, or an element declaration) with any given name.
/// An attempt to compile two different schemas in the same namespace will usually
/// therefore fail.
/// As soon as a type definition or element declaration is used for the first
/// time in a validation episode, it is marked as being "sealed": this prevents subsequent
/// modifications to the component. Examples of modifications that are thereby disallowed
/// include adding to the substitution group of an existing element declaration, adding subtypes
/// to an existing type, or redefining components using <xs:redefine>
///
[Serializable]
public class SchemaManager {
private JConfiguration config;
private IList errorList = null;
// internal constructor: the public interface is a factory method
// on the Processor object
internal SchemaManager(net.sf.saxon.Configuration config) {
this.config = (JConfiguration)config;
}
///
/// The SchemaResolver is a user-supplied class used for resolving references to
/// schema documents. It applies to references from one schema document to another
/// appearing in xs:import , xs:include , and xs:redefine ; to
/// references from an instance document to a schema in xsi:schemaLocation and
/// xsi:noNamespaceSchemaLocation , to xsl:import-schema in XSLT, and to
/// the import schema declaration in XQuery.
///
public SchemaResolver SchemaResolver {
get {
SchemaURIResolver r = config.getSchemaURIResolver();
if (r is DotNetSchemaURIResolver) {
return ((DotNetSchemaURIResolver)r).resolver;
} else {
return null;
}
}
set {
config.setSchemaURIResolver(new DotNetSchemaURIResolver(value));
}
}
///
/// List of errors. The caller may supply an empty list before calling Compile;
/// the processor will then populate the list with error information obtained during
/// the schema compilation. Each error will be included as an object of type StaticError.
/// If no error list is supplied by the caller, error information will be written to
/// the standard error stream.
///
///
/// By supplying a custom List with a user-written add() method, it is possible to
/// intercept error conditions as they occur.
/// Note that this error list is used only for errors detected during the compilation
/// of the schema. It is not used for errors detected when using the schema to validate
/// a source document.
///
public IList ErrorList {
set {
errorList = value;
}
get {
return errorList;
}
}
///
/// Compile a schema supplied as a Stream. The resulting schema components are added
/// to the cache.
///
/// A stream containing the source text of the schema
/// The base URI of the schema document, for resolving any references to other
/// schema documents
public void Compile(Stream input, Uri baseUri) {
StreamSource ss = new StreamSource(new DotNetInputStream(input));
ss.setSystemId(baseUri.ToString());
if (errorList == null) {
config.addSchemaSource(ss);
} else {
config.addSchemaSource(ss, new ErrorGatherer(errorList));
}
}
///
/// Compile a schema, retrieving the source using a URI. The resulting schema components are added
/// to the cache.
///
///
/// The document located via the URI is parsed using the System.Xml parser.
///
/// The URI identifying the location where the schema document can be
/// found
public void Compile(Uri uri) {
StreamSource ss = new StreamSource(uri.ToString());
AugmentedSource aug = AugmentedSource.makeAugmentedSource(ss);
aug.setPleaseCloseAfterUse(true);
if (errorList == null) {
config.addSchemaSource(aug);
} else {
config.addSchemaSource(aug, new ErrorGatherer(errorList));
}
}
///
/// Compile a schema, delivered using an XmlReader. The resulting schema components are added
/// to the cache.
///
///
/// The XmlReader is responsible for parsing the document; this method builds a tree
/// representation of the document (in an internal Saxon format) and compiles it.
/// If the XmlReader is an XmlTextReader , Saxon will set its Normalization
/// property to true, and will wrap it in a (non-validating) XmlValidatingReader to ensure
/// that entity references are expanded.
///
public void Compile(XmlReader reader) {
if (reader is XmlTextReader) {
((XmlTextReader)reader).Normalization = true;
reader = new XmlValidatingReader(reader);
((XmlValidatingReader)reader).ValidationType = ValidationType.None;
}
PullProvider pp = new DotNetPullProvider(reader);
pp.setPipelineConfiguration(config.makePipelineConfiguration());
// pp = new PullTracer(pp); /* diagnostics */
PullSource ss = new PullSource(pp);
ss.setSystemId(reader.BaseURI);
if (errorList == null) {
config.addSchemaSource(ss);
} else {
config.addSchemaSource(ss, new ErrorGatherer(errorList));
}
}
///
/// Compile a schema document, located at an XdmNode. This may be a document node whose
/// child is an xs:schema element, or it may be
/// the xs:schema element itself. The resulting schema components are added
/// to the cache.
///
public void Compile(XdmNode node) {
ErrorGatherer eg = null;
if (errorList != null) {
eg = new ErrorGatherer(errorList);
}
config.readInlineSchema((NodeInfo)node.value, null, eg);
}
///
/// Create a new SchemaValidator , which may be used for validating instance
/// documents.
///
///
/// The SchemaValidator uses the cache of schema components held by the
/// SchemaManager . It may also add new components to this cache (for example,
/// when the instance document references a schema using xsi:schemaLocation ).
/// It is also affected by changes to the schema cache that occur after the
/// SchemaValidator is created.
/// When schema components are used for validating instance documents (or for compiling
/// schema-aware queries and stylesheets) they are sealed to prevent subsequent modification.
/// The modifications disallowed once a component is sealed include adding to the substitution group
/// of an element declaration, adding subtypes derived by extension to an existing complex type, and
/// use of <xs:redefine>
///
public SchemaValidator NewSchemaValidator() {
return new SchemaValidator(config);
}
}
///
/// 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. 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.
///
[Serializable]
public class SchemaValidator {
private JConfiguration config;
private bool lax = false;
private Source source;
private XmlDestination destination;
private IList errorList = null;
// internal constructor
internal SchemaValidator(JConfiguration config) {
this.config = config;
}
///
/// The validation mode may be either strict or lax. The default is strict;
/// this property is set 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.
///
public bool IsLax {
get { return lax; }
set { lax = value; }
}
///
/// Supply the instance document to be validated in the form of a Stream
///
/// A stream containing the XML document to be parsed
/// and validated.
/// The base URI to be used for resolving any relative
/// references, for example a reference to an xsi:schemaLocation
public void SetSource(Stream source, Uri baseUri) {
StreamSource ss = new StreamSource(new DotNetInputStream(source));
ss.setSystemId(baseUri.ToString());
this.source = ss;
}
///
/// Supply the instance document to be validated in the form of a Uri reference
///
///
/// The supplied node must be either a document node or an element node.
/// If an element node is supplied, then the subtree rooted at this element is
/// validated as if it were a complete document: that is, it must not only conform
/// to the structure required of that element, but any referential constraints
/// (keyref, IDREF) must be satisfied within that subtree.
///
///
/// URI of the document to be validated
public void SetSource(Uri baseUri) {
StreamSource ss = new StreamSource(baseUri.ToString());
AugmentedSource aug = AugmentedSource.makeAugmentedSource(ss);
aug.setPleaseCloseAfterUse(true);
this.source = aug;
}
///
/// Supply the instance document to be validated, in the form of an XmlReader.
///
///
/// The XmlReader is responsible for parsing the document; this method validates it.
///
/// The XmlReader used to read and parse the instance
/// document being validated. This is used as supplied. For conformance, use of a
/// plain XmlTextReader is discouraged, because it does not expand entity
/// references. This may cause validation failures.
///
public void SetSource(XmlReader reader) {
PullProvider pp = new DotNetPullProvider(reader);
pp.setPipelineConfiguration(config.makePipelineConfiguration());
// pp = new PullTracer(pp); /* diagnostics */
PullSource psource = new PullSource(pp);
psource.setSystemId(reader.BaseURI);
this.source = psource;
}
///
/// Supply the instance document to be validated in the form of an XdmNode
///
///
/// The supplied node must be either a document node or an element node.
/// If an element node is supplied, then the subtree rooted at this element is
/// validated as if it were a complete document: that is, it must not only conform
/// to the structure required of that element, but any referential constraints
/// (keyref, IDREF) must be satisfied within that subtree.
///
///
/// The document or element node at the root of the tree
/// to be validated
public void SetSource(XdmNode source) {
this.source = (NodeInfo)source.value;
}
///
/// Supply the destination to hold the validated document. If no destination
/// is supplied, the validated document is discarded.
///
///
/// The destination differs from the source in that (a) default values of missing
/// elements and attributes are supplied, and (b) the typed values of elements and
/// attributes are available. However, typed values can only be accessed if the result
/// is represented using the XDM data model, that is, if the destination is supplied
/// as an XdmDestination.
///
public void SetDestination(XmlDestination destination) {
this.destination = destination;
}
///
/// List of errors. The caller may supply an empty list before calling Compile;
/// the processor will then populate the list with error information obtained during
/// the schema compilation. Each error will be included as an object of type StaticError.
/// If no error list is supplied by the caller, error information will be written to
/// the standard error stream.
///
///
/// By supplying a custom List with a user-written add() method, it is possible to
/// intercept error conditions as they occur.
/// Note that this error list is used only for errors detected while
/// using the schema to validate a source document. It is not used to report errors
/// in the schema itself.
///
public IList ErrorList {
set {
errorList = value;
}
get {
return errorList;
}
}
///
/// Run the validation of the supplied source document, optionally
/// writing the validated document to the supplied destination.
///
public void Run() {
AugmentedSource aug = AugmentedSource.makeAugmentedSource(source);
aug.setSchemaValidationMode(lax ? Validation.LAX : Validation.STRICT);
JReceiver receiver;
if (destination == null) {
receiver = new Sink();
} else if (destination is Serializer) {
receiver = ((Serializer)destination).GetReceiver(config);
} else {
Result result = destination.GetResult();
if (result is JReceiver) {
receiver = (JReceiver)result;
} else {
throw new ArgumentException("Unknown type of destination");
}
}
PipelineConfiguration pipe = config.makePipelineConfiguration();
if (errorList != null) {
pipe.setErrorListener(new ErrorGatherer(errorList));
}
new Sender(pipe).send(aug, receiver, true);
}
}
///
/// The SchemaResolver is a user-supplied class used for resolving references to
/// schema documents. It applies to references from one schema document to another
/// appearing in xs:import , xs:include , and xs:redefine ; to
/// references from an instance document to a schema in xsi:schemaLocation and
/// xsi:noNamespaceSchemaLocation , to xsl:import-schema in XSLT, and to
/// the import schema declaration in XQuery.
///
public interface SchemaResolver {
///
/// Given a targetNamespace and a set of location hints, return a set of schema documents.
///
/// The target namespace of the required schema components
/// The base URI of the module containing the reference to a schema document
/// declaration
/// The sequence of URIs (if any) listed as location hints.
/// In most cases there will only be one; but the import schema declaration in
/// XQuery permits several.
/// A set of absolute Uris identifying the query modules to be loaded. There is no requirement
/// that these correspond one-to-one with the URIs defined in the locationHints . The
/// returned URIs will be dereferenced by calling the GetEntity method.
///
Uri[] GetSchemaDocuments(String targetNamespace, Uri baseUri, String[] locationHints);
///
/// Dereference a URI returned by GetModules to retrieve a Stream containing
/// the actual XML schema document.
///
/// A URI returned by the GetSchemaDocuments
method.
/// Either a Stream or a String containing the query text.
/// The supplied URI will be used as the base URI of the query module.
Object GetEntity(Uri absoluteUri);
}
// internal class that wraps a (.NET) QueryResolver to create a (Java) SchemaURIResolver
internal class DotNetSchemaURIResolver : net.sf.saxon.type.SchemaURIResolver {
internal SchemaResolver resolver;
public DotNetSchemaURIResolver(SchemaResolver resolver) {
this.resolver = resolver;
}
public Source[] resolve(String targetNamespace, String baseURI, String[] locations) {
Uri baseU = (baseURI == null ? null : new Uri(baseURI));
Uri[] modules = resolver.GetSchemaDocuments(targetNamespace, baseU, locations);
StreamSource[] ss = new StreamSource[modules.Length];
for (int i = 0; i < ss.Length; i++) {
ss[i] = new StreamSource();
ss[i].setSystemId(modules[i].ToString());
Object doc = resolver.GetEntity(modules[i]);
if (doc is Stream) {
ss[i].setInputStream(new DotNetInputStream((Stream)doc));
} else if (doc is String) {
ss[i].setReader(new DotNetReader(new StringReader((String)doc)));
} else {
throw new ArgumentException("Invalid response from GetEntity()");
}
}
return ss;
}
}
}
//
// 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.
//
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
// Contributor(s): none.
//
© 2015 - 2025 Weber Informatics LLC | Privacy Policy