Project

Profile

Help

How to connect?
Download (34.3 KB) Statistics
| Branch: | Tag: | Revision:

he / latest9.9 / hen / csource / api / Saxon.Api / Schema.cs @ a2e6e9df

1
using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections.Generic;
5
using JAugmentedSource = net.sf.saxon.lib.AugmentedSource;
6
using JConfiguration = net.sf.saxon.Configuration;
7
using JFeatureKeys = net.sf.saxon.lib.FeatureKeys;
8
using JSchemaURIResolver = net.sf.saxon.lib.SchemaURIResolver;
9
using JAtomicType = net.sf.saxon.type.AtomicType;
10
using JSchemaType = net.sf.saxon.type.SchemaType;
11
using JBuiltInAtomicType = net.sf.saxon.type.BuiltInAtomicType;
12
using JValidation = net.sf.saxon.lib.Validation;
13
using JNodeInfo = net.sf.saxon.om.NodeInfo;
14
using JPullSource = net.sf.saxon.pull.PullSource;
15
using JPullProvider = net.sf.saxon.pull.PullProvider;
16
using JPipelineConfiguration = net.sf.saxon.@event.PipelineConfiguration;
17
using JIterator = java.util.Iterator;
18
using JDotNetInputStream = net.sf.saxon.dotnet.DotNetInputStream;
19
using JDotNetPullProvider = net.sf.saxon.dotnet.DotNetPullProvider;
20
using JDotNetReader = net.sf.saxon.dotnet.DotNetReader;
21
using JSchemaException = net.sf.saxon.type.SchemaException;
22
using JItemTypeFactory = net.sf.saxon.s9api.ItemTypeFactory;
23
using JSource = javax.xml.transform.Source;
24
using JStreamSource = javax.xml.transform.stream.StreamSource;
25
using JSchemaValidator = net.sf.saxon.s9api.SchemaValidator;
26

    
27
namespace Saxon.Api
28
{
29

    
30
    /// <summary>
31
    /// A <c>SchemaManager</c> is responsible for compiling schemas and
32
    /// maintaining a cache of compiled schemas that can be used for validating
33
    /// instance documents.
34
    /// </summary>
35
    /// <remarks>
36
    /// <para>To obtain a <c>SchemaManager</c>, use the 
37
    /// <c>SchemaManager</c> property of the <c>Processor</c> object.</para>
38
	/// <para>In a schema-aware <c>Processor</c> there is exactly one
39
	/// <c>SchemaManager</c> (in a non-schema-aware <c>Processor</c> there is none).</para>
40
    /// <para>The cache of compiled schema definitions can include only one schema
41
    /// component (for example a type, or an element declaration) with any given name.
42
    /// An attempt to compile two different schemas in the same namespace will usually
43
    /// therefore fail.</para>
44
    /// <para>As soon as a type definition or element declaration is used for the first
45
    /// time in a validation episode, it is marked as being "sealed": this prevents subsequent
46
    /// modifications to the component. Examples of modifications that are thereby disallowed
47
    /// include adding to the substitution group of an existing element declaration, adding subtypes
48
	/// to an existing type, or redefining components using <c>&lt;xs:redefine&gt;</c>.</para>
49
    /// </remarks>
50

    
51
    [Serializable]
52
    public class SchemaManager
53
    {
54

    
55
        private JConfiguration config;
56
        private IList<StaticError> errorList = null;
57
        private net.sf.saxon.s9api.SchemaManager schemaManager;
58
		private Processor processor;
59

    
60

    
61
		// internal constructor
62

    
63
        internal SchemaManager(Processor processor)
64
        {
65
			this.processor = processor;
66
			this.schemaManager = processor.JProcessor.getSchemaManager();
67
			this.config = (JConfiguration)processor.Implementation;
68
        }
69

    
70
        /// <summary>
71
		/// The version of the W3C XML Schema Specification handled by this <c>SchemaManager</c>.
72
        /// </summary>
73
        /// <remarks>
74
		/// <para>The value must be "1.0" (indicating XML Schema 1.0) or "1.1" (indicating XML Schema 1.1).
75
        /// The default is "1.0". New constructs defined in XSD 1.1 are rejected unless this property
76
        /// is set to "1.1" before compiling the schema.
77
        /// </para>
78
        /// </remarks>
79
        /// 
80
        public String XsdVersion {
81
            get {
82
				return schemaManager.getXsdVersion();
83
            }
84
            set {
85
				schemaManager.setXsdVersion (value);
86
            }
87
        }
88

    
89

    
90
        /// <summary>
91
        /// This property provides a way to set the catalog file which will be used by the Apache catalog resolver.
92
        /// </summary>
93
        
94
		public String Catalog
95
        {
96
            set {
97
                net.sf.saxon.trans.XmlCatalogResolver.setCatalog(value, this.config, false);
98
            }
99
        }
100

    
101

    
102
        /// <summary>
103
		/// The <c>SchemaResolver</c> is a user-supplied class used for resolving references to
104
        /// schema documents. It applies to references from one schema document to another
105
        /// appearing in <c>xs:import</c>, <c>xs:include</c>, and <c>xs:redefine</c>; to
106
        /// references from an instance document to a schema in <c>xsi:schemaLocation</c> and
107
        /// <c>xsi:noNamespaceSchemaLocation</c>, to <c>xsl:import-schema</c> in XSLT, and to
108
        /// the <c>import schema</c> declaration in XQuery.
109
        /// </summary>
110

    
111
        public SchemaResolver SchemaResolver
112
        {
113
            get
114
            {
115
                JSchemaURIResolver r = schemaManager.getSchemaURIResolver();
116
                if (r is DotNetSchemaURIResolver)
117
                {
118
                    return ((DotNetSchemaURIResolver)r).resolver;
119
                }
120
                else
121
                {
122
                    return null;
123
                }
124
            }
125
            set
126
            {
127
                schemaManager.setSchemaURIResolver(new DotNetSchemaURIResolver(value));
128
            }
129
        }
130

    
131
        /// <summary>
132
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
133
        /// the processor will then populate the list with error information obtained during
134
		/// the schema compilation. Each error will be included as an object of type <c>StaticError</c>.
135
        /// If no error list is supplied by the caller, error information will be written to
136
        /// the standard error stream.
137
        /// </summary>
138
        /// <remarks>
139
		/// <para>By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
140
        /// intercept error conditions as they occur.</para>
141
        /// <para>Note that this error list is used only for errors detected during the compilation
142
        /// of the schema. It is not used for errors detected when using the schema to validate
143
        /// a source document.</para>
144
        /// </remarks>
145

    
146
        public IList<StaticError> ErrorList
147
        {
148
            set
149
            {
150
                errorList = value;
151
                schemaManager.setErrorListener(new ErrorGatherer(errorList));
152
            }
153
            get
154
            {
155
                return errorList;
156
            }
157
        }
158

    
159

    
160

    
161

    
162
        /// <summary>
163
		/// Compile a schema supplied as a <c>Stream</c>. The resulting schema components are added
164
        /// to the cache.
165
        /// </summary>
166
        /// <param name="input">A stream containing the source text of the schema. This method
167
        /// will consume the supplied stream. It is the caller's responsibility to close the stream
168
        /// after use.</param>
169
        /// <param name="baseUri">The base URI of the schema document, for resolving any references to other
170
        /// schema documents</param>        
171

    
172
        public void Compile(Stream input, Uri baseUri)
173
        {
174
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
175
            ss.setSystemId(baseUri.ToString());
176
			schemaManager.load (ss);
177
        }
178

    
179
        /// <summary>
180
        /// Compile a schema, retrieving the source using a URI. The resulting schema components are added
181
        /// to the cache.
182
        /// </summary>
183
        /// <remarks>
184
        /// The document located via the URI is parsed using the <c>System.Xml</c> parser.
185
        /// </remarks>
186
        /// <param name="uri">The URI identifying the location where the schema document can be
187
        /// found</param>
188

    
189
        public void Compile(Uri uri)
190
        {
191
            JStreamSource ss = new JStreamSource(uri.ToString());
192
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
193
            aug.setPleaseCloseAfterUse(true);
194
			schemaManager.load (aug);
195
        }
196

    
197
        /// <summary>
198
		/// Compile a schema, delivered using an <c>XmlReader</c>. The resulting schema components are added
199
        /// to the cache.
200
        /// </summary>
201
        /// <remarks>
202
        /// The <c>XmlReader</c> is responsible for parsing the document; this method builds a tree
203
        /// representation of the document (in an internal Saxon format) and compiles it.
204
        /// The <c>XmlReader</c> is used as supplied; it is the caller's responsibility to ensure that
205
        /// its settings are appropriate for parsing a schema document (for example, that entity references
206
        /// are expanded and whitespace is retained).
207
        /// </remarks>
208
		/// <param name="reader">The <c>XmlReader</c> (that is, the XML parser) used to supply the source schema document</param>
209

    
210
        public void Compile(XmlReader reader)
211
        {
212
            JPullProvider pp = new JDotNetPullProvider(reader);
213
            pp.setPipelineConfiguration(config.makePipelineConfiguration());
214
            // pp = new PullTracer(pp);  /* diagnostics */
215
            JPullSource ss = new JPullSource(pp);
216
            ss.setSystemId(reader.BaseURI);
217
			schemaManager.load (ss);
218
        }
219

    
220
        /// <summary>
221
		/// Compile a schema document, located at an <c>XdmNode</c>. This may be a document node whose
222
        /// child is an <c>xs:schema</c> element, or it may be
223
        /// the <c>xs:schema</c> element itself. The resulting schema components are added
224
        /// to the cache.
225
        /// </summary>
226
        /// <param name="node">The document node or the outermost element node of a schema document.</param>
227

    
228
        public void Compile(XdmNode node)
229
        {
230
            ErrorGatherer eg = null;
231
            if (errorList != null)
232
            {
233
                eg = new ErrorGatherer(errorList);
234
            }
235
            try
236
            {
237
                config.readInlineSchema((JNodeInfo)node.value, null, eg);
238
            }
239
            catch (JSchemaException e)
240
            {
241
                throw new StaticError(e);
242
            }
243
        }
244

    
245
        /// <summary>
246
        /// Create a new <c>SchemaValidator</c>, which may be used for validating instance
247
        /// documents.
248
        /// </summary>
249
        /// <remarks>
250
        /// <para>The <c>SchemaValidator</c> uses the cache of schema components held by the
251
        /// <c>SchemaManager</c>. It may also add new components to this cache (for example,
252
        /// when the instance document references a schema using <c>xsi:schemaLocation</c>).
253
        /// It is also affected by changes to the schema cache that occur after the 
254
        /// <c>SchemaValidator</c> is created.</para>
255
        /// <para>When schema components are used for validating instance documents (or for compiling
256
        /// schema-aware queries and stylesheets) they are <i>sealed</i> to prevent subsequent modification.
257
        /// The modifications disallowed once a component is sealed include adding to the substitution group
258
        /// of an element declaration, adding subtypes derived by extension to an existing complex type, and
259
        /// use of <c>&lt;xs:redefine&gt;</c>.</para>
260
        /// </remarks>
261

    
262
        public SchemaValidator NewSchemaValidator()
263
        {
264
			return new SchemaValidator(schemaManager.newSchemaValidator(), processor);
265
        }
266

    
267
        /// <summary>
268
		/// Factory method to get an <c>AtomicType</c> object representing the atomic type with a given <c>QName</c>.
269
        /// </summary>
270
        /// <remarks>
271
		/// It is undefined whether two calls on this method supplying the same <c>QName</c> will return the same
272
        /// <c>XdmAtomicType</c> object instance.
273
        /// </remarks>
274
		/// <param name="qname">The <c>QName</c> of the required type</param>
275
        /// <returns>An <c>AtomicType</c> object representing this type if it is present in this schema (and is an
276
        /// atomic type); otherwise, null. </returns>
277

    
278
        public XdmAtomicType GetAtomicType(QName qname)
279
        {
280
			JSchemaType type = config.getSchemaType(qname.ToStructuredQName());
281
            if (type is JBuiltInAtomicType)
282
            {
283
                return XdmAtomicType.BuiltInAtomicType(qname);
284
            }
285
            else if (type is JAtomicType)
286
            {
287
                JItemTypeFactory factory = new JItemTypeFactory(processor.JProcessor);
288
                return new XdmAtomicType(factory.getAtomicType(qname.UnderlyingQName()));
289
            }
290
            else
291
            {
292
                return null;
293
            }
294
        }
295

    
296
    }
297

    
298
    /// <summary>
299
    /// A <c>SchemaValidator</c> is an object that is used for validating instance documents
300
    /// against a schema. The schema consists of the collection of schema components that are
301
    /// available within the schema cache maintained by the <c>SchemaManager</c>, together with
302
    /// any additional schema components located during the course of validation by means of an
303
    /// <c>xsl:schemaLocation</c> or <c>xsi:noNamespaceSchemaLocation</c> attribute within the
304
    /// instance document.
305
    /// </summary>
306
    /// <remarks>
307
    /// If validation fails, an exception is thrown. If validation succeeds, the validated
308
    /// document can optionally be written to a specified destination. This will be a copy of
309
    /// the original document, augmented with default values for absent elements and attributes,
310
    /// and carrying type annotations derived from the schema processing. Saxon does not deliver
311
    /// the full PSVI as described in the XML schema specifications, only the subset of the
312
    /// PSVI properties featured in the XDM data model.
313
    /// </remarks>    
314

    
315
    [Serializable]
316
    public class SchemaValidator
317
    {
318

    
319
        private JConfiguration config;
320
        private bool lax = false;
321
        private JSource source;
322
        private List<JSource> sources = new List<JSource>();
323
        private IList<ValidationFailure> errorList = null;
324
        private Processor processor = null;
325
        private JSchemaValidator schemaValidator;
326
        private JSchemaType documentElementType; 
327

    
328
        // internal constructor
329

    
330
        internal SchemaValidator(JSchemaValidator validator, Processor processor)
331
        {
332
            this.processor = processor;
333
            this.schemaValidator = validator;
334
            this.config = processor.Implementation;
335
        }
336

    
337
        /// <summary>
338
        /// The validation mode may be either strict or lax. The default is strict;
339
        /// this property is set to indicate that lax validation is required. With strict validation,
340
        /// validation fails if no element declaration can be located for the outermost element. With lax
341
        /// validation, the absence of an element declaration results in the content being considered valid.
342
        /// </summary>
343

    
344
        public bool IsLax
345
        {
346
            get { return schemaValidator.isLax(); }
347
            set { schemaValidator.setLax(value); }
348
        }
349

    
350
        /// <summary>
351
        /// This property defines whether the schema processor will recognize, and attempt to
352
        /// dereference, any <c>xsi:schemaLocation</c> and <c>xsi:noNamespaceSchemaLocation</c>
353
        /// attributes encountered in the instance document. The default value is true.
354
        /// </summary>
355

    
356
        public Boolean UseXsiSchemaLocation
357
        {
358
            get
359
            {
360
                return schemaValidator.isUseXsiSchemaLocation();
361
            }
362
            set
363
            {
364
                schemaValidator.setUseXsiSchemaLocation(value);
365
            }
366
        }
367

    
368

    
369
        /// <summary>Set the validation reporting feature, which saves the validation errors in an XML file</summary>
370
        /// <param name="destination"> destination where XML will be sent</param>
371

    
372
        public void SetValidityReporting(XmlDestination destination) {
373
            schemaValidator.setValidityReporting(destination.GetUnderlyingDestination());
374
        }
375

    
376

    
377

    
378
        /// <summary>Set the <c>InvalidityHandler</c> to be used when validating instance documents</summary>
379
        /// <param name="inHandler">the <c>InvalidityHandler</c> to be used</param>
380

    
381
        public void SetInvalidityHandler(IInvalidityHandler inHandler) {
382
            schemaValidator.setInvalidityHandler(new InvalidityHandlerWrapper(inHandler));
383
        }
384

    
385
        /// <summary>
386
        /// Add an instance document to the list of documents to be validated.
387
        /// </summary>
388
        /// <param name="source">Source document supplied as a <c>Stream</c></param>
389
        /// <param name="baseUri">Base URI of the source document</param>
390

    
391
        public void AddSource(Stream source, Uri baseUri) {
392
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(source));
393
            ss.setSystemId(baseUri.ToString());
394
            sources.Add(ss);
395
        }
396

    
397
        /// <summary>
398
        /// Add an instance document to the list of documents to be validated
399
        /// </summary>
400
        /// <param name="uri">URI of the source document</param>
401

    
402
        public void AddSource(Uri uri) {
403
            JStreamSource ss = new JStreamSource(uri.ToString());
404
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
405
            aug.setPleaseCloseAfterUse(true);
406
            sources.Add(aug);
407
        }
408

    
409
        /// <summary>
410
        /// Add an instance document to the list of documents to be validated
411
        /// </summary>
412
        /// <param name="reader">Source document supplied as an <c>XmlReader</c></param>
413

    
414
        public void AddSource(XmlReader reader) {
415
            JPullProvider pp = new JDotNetPullProvider(reader);
416
            JPipelineConfiguration pipe = config.makePipelineConfiguration();
417
            pipe.setUseXsiSchemaLocation(schemaValidator.isUseXsiSchemaLocation());
418
            pp.setPipelineConfiguration(pipe);
419
            // pp = new PullTracer(pp);  /* diagnostics */
420
            JPullSource psource = new JPullSource(pp);
421
            psource.setSystemId(reader.BaseURI);
422
            sources.Add(psource);
423
        }
424

    
425
        /// <summary>
426
        /// Add an instance document to the list of documents to be validated.
427
        /// </summary>
428
        /// <param name="source">Source document supplied as an <c>XdmNode</c> value</param>
429

    
430
        public void AddSource(XdmNode source) {
431
            sources.Add((JNodeInfo)source.value);
432
        }
433

    
434
        /// <summary>
435
		/// Supply the instance document to be validated in the form of a <c>Stream</c>
436
        /// </summary>
437
        /// <param name="source">A stream containing the XML document to be parsed
438
        /// and validated. This stream will be consumed by the validation process,
439
        /// but it will not be closed after use: that is the responsibility of the
440
        /// caller.</param>
441
        /// <param name="baseUri">The base URI to be used for resolving any relative
442
        /// references, for example a reference to an <c>xsi:schemaLocation</c></param>                  
443

    
444
        public void SetSource(Stream source, Uri baseUri)
445
        {
446
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(source));
447
            ss.setSystemId(baseUri.ToString());
448
            this.source = ss;
449
            sources.Clear();
450
        }
451

    
452
        /// <summary>
453
		/// Supply the instance document to be validated in the form of a <c>Uri</c> reference
454
        /// </summary>
455
        /// <param name="uri">URI of the document to be validated</param>                  
456

    
457
        public void SetSource(Uri uri)
458
        {
459
            JStreamSource ss = new JStreamSource(uri.ToString());
460
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
461
            aug.setPleaseCloseAfterUse(true);
462
            this.source = aug;
463
            sources.Clear();
464
        }
465

    
466
        /// <summary>
467
		/// Supply the instance document to be validated, in the form of an <c>XmlReader</c>.
468
        /// </summary>
469
        /// <remarks>
470
		/// The <c>XmlReader</c> is responsible for parsing the document; this method validates it.
471
        /// </remarks>
472
        /// <param name="reader">The <c>XmlReader</c> used to read and parse the instance
473
        /// document being validated. This is used as supplied. For conformance, use of a
474
        /// plain <c>XmlTextReader</c> is discouraged, because it does not expand entity
475
        /// references. This may cause validation failures.
476
        /// </param>
477

    
478
        public void SetSource(XmlReader reader)
479
        {
480
            JPullProvider pp = new JDotNetPullProvider(reader);
481
            JPipelineConfiguration pipe = config.makePipelineConfiguration();
482
            pipe.setUseXsiSchemaLocation(schemaValidator.isUseXsiSchemaLocation());
483
            pp.setPipelineConfiguration(pipe);
484
            // pp = new PullTracer(pp);  /* diagnostics */
485
            JPullSource psource = new JPullSource(pp);
486
            psource.setSystemId(reader.BaseURI);
487
            this.source = psource;
488
            sources.Clear();
489
        }
490

    
491
        /// <summary>
492
		/// Supply the instance document to be validated in the form of an <c>XdmNode</c>.
493
        /// </summary>
494
        /// <remarks>
495
        /// <para>The supplied node must be either a document node or an element node.
496
        /// If an element node is supplied, then the subtree rooted at this element is
497
        /// validated as if it were a complete document: that is, it must not only conform
498
        /// to the structure required of that element, but any referential constraints
499
        /// (keyref, IDREF) must be satisfied within that subtree.
500
        /// </para>
501
        /// </remarks>
502
        /// <param name="source">The document or element node at the root of the tree
503
        /// to be validated</param>        
504

    
505
        public void SetSource(XdmNode source)
506
        {
507
            this.source = (JNodeInfo)source.value;
508
            sources.Clear();
509
        }
510

    
511
        /// <summary>
512
        /// Supply the destination to hold the validated document. If no destination
513
        /// is supplied, the validated document is discarded.
514
        /// </summary>
515
        /// <remarks>
516
        /// The destination differs from the source in that (a) default values of missing
517
        /// elements and attributes are supplied, and (b) the typed values of elements and
518
        /// attributes are available. However, typed values can only be accessed if the result
519
        /// is represented using the XDM data model, that is, if the destination is supplied
520
		/// as an <c>XdmDestination</c>.
521
        /// </remarks>
522
        /// <param name="destination">
523
        /// The destination to hold the validated document.
524
        /// </param>
525

    
526
        public void SetDestination(XmlDestination destination)
527
        {
528
            schemaValidator.setDestination(destination.GetUnderlyingDestination());
529
        }
530

    
531
        /// <summary>
532
        /// Close the destination, allowing resources to be released. Saxon calls this method
533
        /// when it has finished writing to the destination
534
        /// </summary>
535
        public void Close()
536
        {
537
            schemaValidator.close();
538
        }
539

    
540

    
541
        /// <summary>
542
        /// The name of the required top-level element of the document to be validated (that is, the
543
        /// name of the outermost element of the document).
544
        /// if no value is supplied, there is no constraint on the required type
545
        /// </summary>
546
        public QName DocumentElementName {
547

    
548
            get {
549
                net.sf.saxon.s9api.QName qname = schemaValidator.getDocumentElementName();
550
                return qname == null ? null : new QName(qname.getEQName()); }
551
            set { schemaValidator.setDocumentElementName(value.UnderlyingQName()); }
552

    
553
        }
554

    
555

    
556
        /// <summary>
557
        /// The name of the required type of the top-level element of the document to be validated.
558
        /// QName of the name of the required type of the document element, or null if no value has been set.
559
        /// If no value is supplied, there is no constrin on the required type
560
        /// </summary>
561
        public QName DocumentElementTypeName {
562
            get {
563

    
564
                net.sf.saxon.s9api.QName qtname = schemaValidator.getDocumentElementTypeName();
565
                return qtname == null ? null : new QName(qtname.getEQName());
566
            }
567
            set { schemaValidator.setDocumentElementTypeName(value.UnderlyingQName());
568
                documentElementType = config.getSchemaType(value.ToStructuredQName());
569
            }
570
        }
571

    
572
        internal JSchemaType DocumentElementType {
573

    
574
            get { return documentElementType; }
575
        }
576

    
577
        internal JSchemaValidator UnderlyingSchemaValidator
578
        {
579
            get
580
            {
581
                return schemaValidator;
582
            }
583
        }
584

    
585

    
586
        /// <summary>
587
        /// Set the value of a schema parameter (a parameter defined in the schema using the <c>saxon:param</c> extension)
588
        /// </summary>
589
        /// <param name="name">the name of the schema parameter, as a QName</param>
590
        /// <param name="value">the value of the schema  parameter, or null to clear a previously set value</param>
591
        public void SetParameter(QName name, XdmValue value) {
592
            try {
593
                schemaValidator.setParameter(name.UnderlyingQName(), value == null ? null : XdmValue.FromGroundedValueToJXdmValue(value.value));
594
            } catch (net.sf.saxon.s9api.SaxonApiUncheckedException ex) {
595
                throw new StaticError(ex);
596
            }
597
            
598
        }
599

    
600

    
601
        /// <summary>
602
        /// Get the value that has set for a schema processor (a parameter defined in the schema using the <c>saxon:param</c>
603
        /// extension)
604
        /// </summary>
605
        /// <param name="name">the parameter whose name is required</param>
606
        /// <returns>the value that has been set for the parameter, or the EmptySequence if no value has been set</returns>
607
        public XdmValue GetParameter(QName name)
608
        {
609
            net.sf.saxon.s9api.XdmValue value = schemaValidator.getParameter(name.UnderlyingQName());
610
            return value == null ? null : XdmValue.Wrap(value.getUnderlyingValue());
611
        }
612
         
613

    
614

    
615
        /// <summary>
616
        /// Ask and set whether attribute defaults defined in a schema are to be expanded or not
617
        /// (by default, fixed and default attribute values are expaned, that is, they are inserted) into
618
        /// the document during validation as if they were present in the instance being validated)
619
        /// </summary>
620
        public bool ExpendAttributeDefaults {
621
            get { return schemaValidator.isExpandAttributeDefaults(); }
622
            set { schemaValidator.setExpandAttributeDefaults(value); }
623
        }
624

    
625
        /// <summary>
626
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
627
        /// the processor will then populate the list with error information obtained during
628
		/// the schema compilation. Each error will be included as an object of type <c>StaticError</c>.
629
        /// If no error list is supplied by the caller, error information will be written to
630
        /// the standard error stream.
631
        /// </summary>
632
        /// <remarks>
633
		/// <para>By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
634
        /// intercept error conditions as they occur.</para>
635
        /// <para>Note that this error list is used only for errors detected while 
636
        /// using the schema to validate a source document. It is not used to report errors
637
        /// in the schema itself.</para>
638
        /// </remarks>
639

    
640
        public IList<ValidationFailure> ErrorList
641
        {
642
            set
643
            {
644
                errorList = value;
645
                schemaValidator.setInvalidityHandler(new InvalidityGatherer(errorList));
646
                
647
            }
648
            get
649
            {
650
                return errorList;
651
            }
652
        }
653
			
654
			
655

    
656

    
657
        /// <summary>
658
        /// Run the validation of the supplied source document, optionally
659
        /// writing the validated document to the supplied destination.
660
        /// </summary>
661

    
662
        public void Run()
663
        {
664

    
665
            if (source == null)
666
            {
667
                if (sources.Count == 0) {
668
                    throw new StaticError(new net.sf.saxon.trans.XPathException("No source(s) set for the SchemaValidator"));
669
                }
670
                java.util.List iter = new java.util.ArrayList();
671
                foreach (JSource src in sources) {
672
                    iter.add(src);
673
                }
674
                try
675
                {
676
                    schemaValidator.validateMultiple(iter);
677
                }
678
                catch (net.sf.saxon.s9api.SaxonApiException ex) {
679
                    throw new StaticError(ex);
680
                }
681
            }
682
            else
683
            {
684
                JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(source);
685
                aug.setSchemaValidationMode(lax ? JValidation.LAX : JValidation.STRICT);
686
                try {
687
                    schemaValidator.validate(aug);
688
                }
689
                catch (net.sf.saxon.s9api.SaxonApiException ex)
690
            {
691
                throw new StaticError(ex);
692
            }
693
        }
694
                
695
        }
696

    
697
    }
698

    
699

    
700
    /// <summary>
701
	/// The <c>SchemaResolver</c> is a user-supplied class used for resolving references to
702
    /// schema documents. It applies to references from one schema document to another
703
    /// appearing in <c>xs:import</c>, <c>xs:include</c>, and <c>xs:redefine</c>; to
704
    /// references from an instance document to a schema in <c>xsi:schemaLocation</c> and
705
    /// <c>xsi:noNamespaceSchemaLocation</c>, to <c>xsl:import-schema</c> in XSLT, and to
706
    /// the <c>import schema</c> declaration in XQuery.
707
    /// </summary>
708

    
709
    public interface SchemaResolver
710
    {
711

    
712
        /// <summary>
713
        /// Given a target namespace and a set of location hints, return a set of schema documents.
714
        /// </summary>
715
        /// <param name="targetNamespace">The target namespace of the required schema components</param>
716
        /// <param name="baseUri">The base URI of the module containing the reference to a schema document
717
        /// declaration</param>
718
        /// <param name="locationHints">The sequence of URIs (if any) listed as location hints.
719
        /// In most cases there will only be one; but the <c>import schema</c> declaration in
720
        /// XQuery permits several.</param>
721
		/// <returns>A set of absolute URIs identifying the schema documents to be loaded. There is no requirement
722
        /// that these correspond one-to-one with the URIs defined in the <c>locationHints</c>. The 
723
        /// returned URIs will be dereferenced by calling the <c>GetEntity</c> method.
724
        /// </returns>
725

    
726
        /**public**/ Uri[] GetSchemaDocuments(String targetNamespace, Uri baseUri, String[] locationHints);
727

    
728
        /// <summary>
729
		/// Dereference a URI returned by <c>GetSchemaDocuments</c> to retrieve a <c>Stream</c> containing
730
        /// the actual XML schema document.
731
        /// </summary>
732
        /// <param name="absoluteUri">A URI returned by the <code>GetSchemaDocuments</code> method.</param>
733
		/// <returns>Either a <c>Stream</c> or a <c>String</c> containing the schema text. 
734
		/// The supplied URI will be used as the base URI of the schema document.</returns>
735

    
736
        /**public**/ Object GetEntity(Uri absoluteUri);
737

    
738
    }
739

    
740

    
741

    
742
    /// <summary>
743
	/// internal class that wraps a (.NET) QueryResolver to create a (Java) SchemaURIResolver
744
    /// </summary>
745

    
746
    internal class DotNetSchemaURIResolver : net.sf.saxon.lib.SchemaURIResolver
747
    {
748

    
749
        internal SchemaResolver resolver;
750
        internal JConfiguration config;
751

    
752
		/// <summary>
753
		/// Initializes a new instance of the <see cref="Saxon.Api.DotNetSchemaURIResolver"/> class.
754
		/// </summary>
755
		/// <param name="resolver">Resolver.</param>
756
        public DotNetSchemaURIResolver(SchemaResolver resolver)
757
        {
758
            this.resolver = resolver;
759
        }
760

    
761
        public void setConfiguration(JConfiguration config)
762
        {
763
            this.config = config;
764
        }
765

    
766
		/// <summary>
767
		/// Resolve the specified targetNamespace, baseURI and locations.
768
		/// </summary>
769
		/// <param name="targetNamespace">Target namespace.</param>
770
		/// <param name="baseURI">BaseURI.</param>
771
		/// <param name="locations">Locations.</param>
772
        public JSource[] resolve(String targetNamespace, String baseURI, String[] locations)
773
        {
774
			if (config.isSchemaAvailable(targetNamespace) && !(java.lang.Boolean.valueOf(((java.lang.Object)config.getConfigurationProperty(JFeatureKeys.MULTIPLE_SCHEMA_IMPORTS)).toString()).booleanValue()))
775
            {
776
                return new JSource[0];
777
            }
778
            Uri baseU = (baseURI == null ? null : new Uri(baseURI));
779
            Uri[] modules = resolver.GetSchemaDocuments(targetNamespace, baseU, locations);
780
            JStreamSource[] ss = new JStreamSource[modules.Length];
781
            for (int i = 0; i < ss.Length; i++)
782
            {
783
                ss[i] = new JStreamSource();
784
                ss[i].setSystemId(modules[i].ToString());
785
                Object doc = resolver.GetEntity(modules[i]);
786
                if (doc is Stream)
787
                {
788
                    ss[i].setInputStream(new JDotNetInputStream((Stream)doc));
789
                }
790
                else if (doc is String)
791
                {
792
                    ss[i].setReader(new JDotNetReader(new StringReader((String)doc)));
793
                }
794
                else
795
                {
796
                    throw new ArgumentException("Invalid response from GetEntity()");
797
                }
798
            }
799
            return ss;
800
        }
801
    }
802

    
803

    
804

    
805

    
806

    
807

    
808
}
809

    
810
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
811
// Copyright (c) 2018 Saxonica Limited.
812
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
813
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
814
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
815
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(9-9/13)