All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aSaxon-B-9-0-0-8sources.api.Saxon.Api.Configuration.cs Maven / Gradle / Ivy

The newest version!
using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Globalization;
using javax.xml.transform;
using javax.xml.transform.stream;
using JBoolean = java.lang.Boolean;
using JConfiguration = net.sf.saxon.Configuration;
using JVersion = net.sf.saxon.Version;
using JDocumentWrapper = net.sf.saxon.dotnet.DocumentWrapper;
using AugmentedSource = net.sf.saxon.AugmentedSource;
using StructuredQName = net.sf.saxon.om.StructuredQName;
using Whitespace = net.sf.saxon.value.Whitespace;
using StaticQueryContext = net.sf.saxon.query.StaticQueryContext;
using net.sf.saxon.om;
using net.sf.saxon.pull;
using net.sf.saxon.dotnet;


namespace Saxon.Api {

    /// 
    /// The Processor class serves three purposes: it allows global Saxon configuration
    /// options to be set; it acts as a factory for generating XQuery, XPath, and XSLT
    /// compilers; and it owns certain shared resources such as the Saxon NamePool and 
    /// compiled schemas. This is the first object that a Saxon application should create. Once
    /// established, a Processor may be used in multiple threads.
    /// 

    [Serializable]
    public class Processor {

        //Transformation data variables
        internal JConfiguration config;
        private SchemaManager schemaManager = null;

        /// 
        /// Create a new Processor
        /// 

        public Processor() {
            config = new JConfiguration();
            config.setURIResolver(new DotNetURIResolver(new XmlUrlResolver()));
            config.setCollectionURIResolver(new DotNetCollectionURIResolver());
        }

        /// 
        /// Create a Processor, indicating whether it is to be schema-aware.
        /// 
        /// Set to true if the Processor is to be schema-aware.
        /// This requires the Saxon-SA product to be installed, with a valid license key.

        public Processor(bool schemaAware) : this(schemaAware, false) { }

        /// 
        /// Create a Processor, indicating whether it is to be schema-aware.
        /// 
        /// Set to true if the Processor is to be schema-aware.
        /// This requires the Saxon-SA product to be installed, with a valid license key.
        /// This option has no effect at this release.

        public Processor(bool schemaAware, bool loadLocally) {
            if (schemaAware) {
                //if (loadLocally) {
                //    Assembly asm = Assembly.Load("saxon8sa");
                //} else {
                //    try {
                //        int[] v = JVersion.getStructuredVersionNumber();
                //        AssemblyName asn = new AssemblyName();
                //        asn.Name = "saxon8sa";
                //        asn.Version = new Version(v[0], v[1], v[2], v[3]);
                //        //asn.Version = new Version(JVersion.getMajorVersion(), JVersion.getMinorVersion());
                //        asn.SetPublicKeyToken(new byte[] { 0xe1, 0xfd, 0xd0, 0x02, 0xd5, 0x08, 0x3f, 0xe6 });
                //        asn.CultureInfo = new CultureInfo("");
                //        Assembly asm = Assembly.Load(asn);
                //        // try to load the saxon8sa.dll assembly
                //        //Assembly asm = Assembly.Load("saxon8sa, Ver=" + JVersion.getProductVersion() + ".0.1, " +
                //        //    @"SN=e1fdd002d5083fe6, Loc=neutral");
                //    } catch (Exception e) {
                //        Console.WriteLine("Cannot load Saxon-SA software (assembly saxon8sa.dll version " +
                //            JVersion.getProductVersion() + ".0.1)");
                //        throw e;
                //    }
                //}
                config = JConfiguration.makeSchemaAwareConfiguration(null, 
                    DotNetPlatform.getSaxonSaFullyQualifiedClassName());
                schemaManager = new SchemaManager(config);
            } else {
                config = new JConfiguration();
            }
            config.setURIResolver(new DotNetURIResolver(new XmlUrlResolver()));
            config.setCollectionURIResolver(new DotNetCollectionURIResolver());
        }

        /// 
        /// Get the full name of the Saxon product version implemented by this Processor
        /// 

        public string ProductTitle {
            get { return JVersion.getProductTitle(); }
        }

        /// 
        /// Get the Saxon product version number (for example, "8.8.1")
        /// 

        public string ProductVersion {
            get { return JVersion.getProductVersion(); }
        }


        /// 
        /// Indicates whether the Processor is schema-aware
        /// 

        public bool IsSchemaAware {
            get { return config.isSchemaAware(JConfiguration.XML_SCHEMA); }
        }

        /// 
        /// Gets the SchemaManager for the Processor. Returns null
        /// if the Processor is not schema-aware.
        /// 

        public SchemaManager SchemaManager {
            get { return schemaManager; }
        }

        /// 
        /// An XmlResolver, which will be used while compiling and running queries, 
        /// XPath expressions, and stylesheets, if no other XmlResolver is nominated
        /// 
        /// 
        /// By default an XmlUrlResolver is used. This means that the responsibility
        /// for resolving and dereferencing URIs rests with the .NET platform, not with the
        /// GNU Classpath.
        /// When Saxon invokes a user-written XmlResolver, the GetEntity method
        /// may return any of: a System.IO.Stream; a System.IO.TextReader; or a
        /// java.xml.transform.Source.
        /// 

        public XmlResolver XmlResolver {
            get {
                return ((DotNetURIResolver)config.getURIResolver()).getXmlResolver();
            }
            set {
                config.setURIResolver(new DotNetURIResolver(value));
            }
        }

        /// 
        /// Create a new DocumentBuilder, which may be used to build XDM documents from
        /// a variety of sources.
        /// 
        /// A new DocumentBuilder

        public DocumentBuilder NewDocumentBuilder() {
            DocumentBuilder builder = new DocumentBuilder(this);
            builder.XmlResolver = XmlResolver;
            return builder;
        }

        /// 
        /// Create a new XQueryCompiler, which may be used to compile XQuery queries.
        /// 
        /// 
        /// The returned XQueryCompiler retains a live link to the Processor, and
        /// may be affected by subsequent changes to the Processor.
        /// 
        /// A new XQueryCompiler

        public XQueryCompiler NewXQueryCompiler() {
            return new XQueryCompiler(this);
        }

        /// 
        /// Create a new XsltCompiler, which may be used to compile XSLT stylesheets.
        /// 
        /// 
        /// The returned XsltCompiler retains a live link to the Processor, and
        /// may be affected by subsequent changes to the Processor.
        /// 
        /// A new XsltCompiler

        public XsltCompiler NewXsltCompiler() {
            return new XsltCompiler(config);
        }

        /// 
        /// Create a new XPathCompiler, which may be used to compile XPath expressions.
        /// 
        /// 
        /// The returned XPathCompiler retains a live link to the Processor, and
        /// may be affected by subsequent changes to the Processor.
        /// 
        /// A new XPathCompiler

        public XPathCompiler NewXPathCompiler() {
            return new XPathCompiler(config);
        }

        /// 
        /// The XML version used in this Processor (for example, this determines what characters
        /// are permitted in a name)
        /// 
        /// 
        /// The value must be 1.0 or 1.1, as a decimal. The default version is currently 1.0, but may
        /// change in the future.
        /// 

        public decimal XmlVersion {
            get {
                return (config.getXMLVersion() == JConfiguration.XML10 ? 1.0m : 1.1m);
            }
            set {
                if (value == 1.0m) {
                    config.setXMLVersion(JConfiguration.XML10);
                } else if (value == 1.1m) {
                    config.setXMLVersion(JConfiguration.XML11);
                } else {
                    throw new ArgumentException("Invalid XML version: " + value);
                }
            }
        }

        /// 
        /// Register a named collection. A collection is identified by a URI (the collection URI),
        /// and its content is represented by an IEnumerable that enumerates the contents
        /// of the collection. The values delivered by this enumeration are Uri values, which 
        /// can be mapped to nodes using the registered XmlResolver.
        /// 
        /// The URI used to identify the collection in a call
        /// of the XPath collection() function. The default collection is registered
        /// by supplying null as the value of this argument (this is the collection returned
        /// when the XPath collection() function is called with no arguments). 
        /// An enumerable object that represents the contents of the
        /// collection, as a sequence of document URIs. The enumerator returned by this
        /// IEnumerable object must return instances of the Uri class.
        /// 
        /// Collections should be stable: that is, two calls to retrieve the same collection URI
        /// should return the same sequence of document URIs. This requirement is imposed by the
        /// W3C specifications, but in the case of a user-defined collection it is not enforced by
        /// the Saxon product.
        /// A collection may be "unregistered" by providing null as the value of the
        /// contents argument. A collection may be replaced by specifying the URI of an existing
        /// collection.
        /// Collections registered with a processor are available to all queries and stylesheets
        /// running under the control that processor. Collections should not normally be registered
        /// while queries and transformations are in progress.
        /// 
        /// 

        public void RegisterCollection(Uri collectionUri, IEnumerable contents) {
            String u = (collectionUri == null ? null : collectionUri.ToString());
            DotNetCollectionURIResolver resolver =
                (DotNetCollectionURIResolver)config.getCollectionURIResolver();
            resolver.registerCollection(u, contents);
        }

        /// 
        /// The underlying Configuration object in the Saxon implementation
        /// 
        /// 
        /// This property provides access to internal methods in the Saxon engine that are
        /// not specifically exposed in the .NET API. In general these methods should be
        /// considered to be less stable than the classes in the Saxon.Api namespace. 
        /// The internal methods follow
        /// Java naming conventions rather than .NET conventions.
        /// Information about the returned object (and the objects it provides access to)
        /// is included in the Saxon JavaDoc docmentation, available 
        /// online.
        /// 
        /// 

        public net.sf.saxon.Configuration Implementation {
            get { return config; }
        }

        /// 
        /// Set a configuration property
        /// 
        /// 
        /// This method provides the ability to set named properties of the configuration.
        /// The property names are set as strings, whose values can be found in the Java
        /// class net.sf.saxon.FeatureKeys. The property values are set as objects
        /// whose type depends on the property.
        /// 
        /// The property name
        /// The property value

        public void SetProperty(String name, Object value) {
            if (value is bool) {
                value = ((bool)value ? JBoolean.TRUE : JBoolean.FALSE);
            }
            config.setConfigurationProperty(name, value);
        }

    }

    /// 
    /// The DocumentBuilder class enables XDM documents to be built from various sources.
    /// The class is always instantiated using the NewDocumentBuilder method
    /// on the Processor object.
    /// 

    [Serializable]
    public class DocumentBuilder {

        private Processor processor;
        private JConfiguration config;
        private XmlResolver xmlResolver;
        private SchemaValidationMode validation;
        private bool dtdValidation;
        private bool lineNumbering;
        private WhitespacePolicy whitespacePolicy;
        private Uri baseUri;
        private QName topLevelElement;

        internal DocumentBuilder(Processor processor) {
            this.processor = processor;
            this.config = processor.Implementation;
        }

        /// 
        /// An XmlResolver, which will be used to resolve URIs of documents being loaded
        /// and of references to external entities within those documents.
        /// 
        /// 
        /// By default an XmlUrlResolver is used. This means that the responsibility
        /// for resolving and dereferencing URIs rests with the .NET platform (and not with the
        /// GNU Classpath).
        /// When Saxon invokes a user-written XmlResolver, the GetEntity method
        /// may return any of: a System.IO.Stream; a System.IO.TextReader; or a
        /// java.xml.transform.Source.
        /// 

        public XmlResolver XmlResolver {
            get {
                return xmlResolver;
            }
            set {
                xmlResolver = value;
            }
        }

        /// 
        /// Determines whether line numbering is enabled for documents loaded using this
        /// DocumentBuilder.
        /// 
        /// 
        /// By default, line numbering is disabled.
        /// Line numbering is not available for all kinds of source: in particular,
        /// it is not available when loading from an existing XmlDocument.
        /// The resulting line numbers are accessible to applications using the
        /// extension function saxon:line-number() applied to a node.  
        /// Line numbers are maintained only for element nodes; the line number
        /// returned for any other node will be that of the most recent element. 
        /// 

        public bool IsLineNumbering {
            get {
                return lineNumbering;
            }
            set {
                lineNumbering = value;
            }
        }

        /// 
        /// Determines whether schema validation is applied to documents loaded using this
        /// DocumentBuilder, and if so, whether it is strict or lax.
        /// 
        /// 
        /// By default, no schema validation takes place.
        /// This option requires the schema-aware version of the Saxon product (Saxon-SA).
        /// 

        public SchemaValidationMode SchemaValidationMode {
            get {
                return validation;
            }
            set {
                validation = value;
            }
        }

        /// 
        /// The required name of the top level element in a document instance being validated
        /// against a schema.
        /// 
        /// 
        /// If this property is set, and if schema validation is requested, then validation will
        /// fail unless the outermost element of the document has the required name.
        /// This option requires the schema-aware version of the Saxon product (Saxon-SA).
        ///  

        public QName TopLevelElementName {
            get {
                return topLevelElement;
            }
            set {
                topLevelElement = value;
            }
        }

        /// 
        /// Determines whether DTD validation is applied to documents loaded using this
        /// DocumentBuilder.
        /// 
        /// 
        ///
        /// By default, no DTD validation takes place.
        /// 
        /// 

        public bool DtdValidation {
            get {
                return dtdValidation;
            }
            set {
                dtdValidation = value;
            }
        }

        /// 
        /// Determines the whitespace stripping policy applied when loading a document
        /// using this DocumentBuilder.
        /// 
        /// 
        /// By default, whitespace text nodes appearing in element-only content
        /// are stripped, and all other whitespace text nodes are retained.
        /// 

        public WhitespacePolicy WhitespacePolicy {
            get {
                return whitespacePolicy;
            }
            set {
                whitespacePolicy = value;
            }
        }

        /// 
        /// The base URI of a document loaded using this DocumentBuilder.
        /// This is used for resolving any relative URIs appearing
        /// within the document, for example in references to DTDs and external entities.
        /// 
        /// 
        /// This information is required when the document is loaded from a source that does not
        /// provide an intrinsic URI, notably when loading from a Stream or a TextReader.
        /// 


        public Uri BaseUri {
            get { return baseUri; }
            set { baseUri = value; }
        }

        /// 
        /// Load an XML document, retrieving it via a URI.
        /// 
        /// 
        /// Note that the type Uri requires an absolute URI.
        /// The URI is dereferenced using the registered XmlResolver.
        /// This method takes no account of any fragment part in the URI.
        /// The role passed to the GetEntity method of the XmlResolver 
        /// is "application/xml", and the required return type is System.IO.Stream.
        /// The document located via the URI is parsed using the System.Xml parser.
        /// Note that the Microsoft System.Xml parser does not report whether attributes are
        /// defined in the DTD as being of type ID and IDREF. This is true whether or not
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
        /// id() and idref() functions.
        /// 
        /// The URI identifying the location where the document can be
        /// found. This will also be used as the base URI of the document (regardless
        /// of the setting of the BaseUri property).
        /// An XdmNode. This will be
        ///  the document node at the root of the tree of the resulting in-memory document. 
        /// 

        public XdmNode Build(Uri uri) {
            baseUri = uri;
            Stream inn = (Stream)XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
            XdmNode outt = Build(inn);
            inn.Close();
            return outt;
        }

        /// 
        /// Load an XML document supplied as raw (lexical) XML on a Stream.
        /// 
        /// 
        /// The document is parsed using the System.Xml parser.
        /// Before calling this method, the BaseUri property must be set to identify the
        /// base URI of this document, used for resolving any relative URIs contained within it.
        /// Note that the Microsoft System.Xml parser does not report whether attributes are
        /// defined in the DTD as being of type ID and IDREF. This is true whether or not
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
        /// id() and idref() functions.         
        /// 
        /// The Stream containing the XML source to be parsed
        /// An XdmNode, the document node at the root of the tree of the resulting
        /// in-memory document
        /// 

        public XdmNode Build(Stream input) {
            if (baseUri == null) {
                throw new ArgumentException("No base URI suppplied");
            }
            Source source = new StreamSource(new DotNetInputStream(input));
            source.setSystemId(baseUri.ToString());
            source = augmentSource(source);
            StaticQueryContext env = new StaticQueryContext(config);
            //env.setURIResolver(new DotNetURIResolver(xmlResolver));
            DocumentInfo doc = env.buildDocument(source);
            return (XdmNode)XdmValue.Wrap(doc);
        }

        private Source augmentSource(Source source) {
            if (validation != SchemaValidationMode.None) {
                source = AugmentedSource.makeAugmentedSource(source);
                if (validation == SchemaValidationMode.Strict) {
                    ((AugmentedSource)source).setSchemaValidationMode(Validation.STRICT);
                } else {
                    ((AugmentedSource)source).setSchemaValidationMode(Validation.LAX);
                }
            }
            if (topLevelElement != null) {
                source = AugmentedSource.makeAugmentedSource(source);
                ((AugmentedSource)source).setTopLevelElement(
                    new StructuredQName(
                        topLevelElement.Prefix, topLevelElement.Uri, topLevelElement.LocalName));
            }    
     
            if (whitespacePolicy != WhitespacePolicy.PreserveAll) {
                source = AugmentedSource.makeAugmentedSource(source);
                if (whitespacePolicy == WhitespacePolicy.StripIgnorable) {
                    ((AugmentedSource)source).setStripSpace(Whitespace.IGNORABLE);
                } else {
                    ((AugmentedSource)source).setStripSpace(Whitespace.ALL);
                }
            }
            if (lineNumbering) {
                source = AugmentedSource.makeAugmentedSource(source);
                ((AugmentedSource)source).setLineNumbering(true);
            }
            if (dtdValidation) {
                source = AugmentedSource.makeAugmentedSource(source);
                ((AugmentedSource)source).setDTDValidationMode(Validation.STRICT);
            }
            return source;
        }

        /// 
        /// Load an XML document, delivered using an XmlReader.
        /// 
        /// 
        /// The XmlReader is responsible for parsing the document; this method builds a tree
        /// representation of the document (in an internal Saxon format) and returns its document node.
        /// The XmlReader is not required to perform validation but it must expand any entity references.
        /// Saxon uses the properties of the XmlReader as supplied.
        /// Use of a plain XmlTextReader is discouraged, because it does not expand entity
        /// references. This should only be used if you know in advance that the document will contain
        /// no entity references (or perhaps if your query or stylesheet is not interested in the content
        /// of text and attribute nodes). Instead, with .NET 1.1 use an XmlValidatingReader (with ValidationType
        /// set to None). The constructor for XmlValidatingReader is obsolete in .NET 2.0,
        /// but the same effect can be achieved by using the Create method of XmlReader with
        /// appropriate XmlReaderSettings
        /// Conformance with the W3C specifications requires that the Normalization property
        /// of an XmlTextReader should be set to true. However, Saxon does not insist
        /// on this.
        /// If the XmlReader performs schema validation, Saxon will ignore any resulting type
        /// information. Type information can only be obtained by using Saxon's own schema validator, which
        /// will be run if the SchemaValidationMode property is set to Strict or Lax
        /// Note that the Microsoft System.Xml parser does not report whether attributes are
        /// defined in the DTD as being of type ID and IDREF. This is true whether or not
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
        /// id() and idref() functions.
        /// 
        /// The XMLReader that supplies the parsed XML source
        /// An XdmNode, the document node at the root of the tree of the resulting
        /// in-memory document
        /// 

        public XdmNode Build(XmlReader reader) {
            PullProvider pp = new DotNetPullProvider(reader);
            pp.setPipelineConfiguration(config.makePipelineConfiguration());
            // pp = new PullTracer(pp);  /* diagnostics */
            Source source = new PullSource(pp);
            source.setSystemId(reader.BaseURI);
            source = augmentSource(source);
            DocumentInfo doc = new StaticQueryContext(config).buildDocument(source);
            return (XdmNode)XdmValue.Wrap(doc);
        }

        /// 
        /// Load an XML DOM document, supplied as an XmlNode, into a Saxon XdmNode.
        /// 
        /// 
        /// 
        /// The returned document will contain only the subtree rooted at the supplied node.
        /// 
        /// 
        /// This method copies the DOM tree to create a Saxon tree. See the Wrap method for
        /// an alternative that creates a wrapper the DOM tree, allowing it to be modified in situ.
        /// 
        /// 
        /// The DOM Node to be copied to form a Saxon tree
        /// An XdmNode, the document node at the root of the tree of the resulting
        /// in-memory document
        /// 

        public XdmNode Build(XmlNode source) {
            return Build(new XmlNodeReader(source));
        }

        /// 
        /// Wrap an XML DOM document, supplied as an XmlNode, as a Saxon XdmNode.
        /// 
        /// 
        /// 
        /// This method must be applied at the level of the Document Node. Unlike the
        /// Build method, the original DOM is not copied. This saves memory and
        /// time, but it also means that it is not possible to perform operations such as
        /// whitespace stripping and schema validation.
        /// 
        /// 
        /// The DOM document node to be wrapped
        /// An XdmNode, the Saxon document node at the root of the tree of the resulting
        /// in-memory document
        /// 

        public XdmNode Wrap(XmlDocument doc) {
            String baseu = (baseUri == null ? null : baseUri.ToString());
            JDocumentWrapper wrapper = new JDocumentWrapper(doc, baseu, config);
            return (XdmNode)XdmValue.Wrap(wrapper);
        }


    }


    /// 
    /// Enumeration identifying the various Schema validation modes
    /// 

    public enum SchemaValidationMode {
        /// No validation 
        None,
        /// Strict validation
        Strict,
        /// Lax validation
        Lax
    }

    /// 
    /// Enumeration identifying the various Whitespace stripping policies
    /// 

    public enum WhitespacePolicy {
        /// No whitespace is stripped 
        PreserveAll,
        /// Whitespace text nodes appearing in element-only content are stripped
        StripIgnorable,
        /// All whitespace text nodes are stripped
        StripAll
    }



}

//
// 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