Project

Profile

Help

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

he / src / main / csharp / api / Saxon.Api / Schema.cs @ 2699858e

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
        private ErrorReporter reporter;
60

    
61

    
62

    
63
		// internal constructor
64

    
65
        internal SchemaManager(Processor processor)
66
        {
67
			this.processor = processor;
68
			this.schemaManager = processor.JProcessor.getSchemaManager();
69
			this.config = (JConfiguration)processor.Implementation;
70
            reporter = null;
71
        }
72

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

    
92

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

    
104

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

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

    
134
        /// <summary>
135
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
136
        /// the processor will then populate the list with error information obtained during
137
		/// the schema compilation. Each error will be included as an object of type <c>StaticError</c>.
138
        /// If no error list is supplied by the caller, error information will be written to
139
        /// the standard error stream.
140
        /// </summary>
141
        /// <remarks>
142
		/// <para>By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
143
        /// intercept error conditions as they occur.</para>
144
        /// <para>Note that this error list is used only for errors detected during the compilation
145
        /// of the schema. It is not used for errors detected when using the schema to validate
146
        /// a source document.</para>
147
        /// </remarks>
148
        [Obsolete("IList<StaticError> ErrorList is deprecated, please use the method SetErrorList and GetErrorList.")]
149
        public IList<StaticError> ErrorList
150
        {
151
            set
152
            {
153
                errorList = value;
154
                reporter = null;
155
                schemaManager.setErrorReporter(new ErrorReporterToStaticError(errorList));
156
            }
157
            get
158
            {
159
                return errorList;
160
            }
161
        }
162

    
163
        /// <summary>
164
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
165
        /// the processor will then populate the list with error information obtained during
166
		/// the schema compilation. Each error will be included as an object of type <c>StaticError</c>.
167
        /// If no error list is supplied by the caller, error information will be written to
168
        /// the standard error stream.
169
        /// </summary>
170
        /// <remarks>
171
		/// <para>By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
172
        /// intercept error conditions as they occur.</para>
173
        /// <para>Note that this error list is used only for errors detected during the compilation
174
        /// of the schema. It is not used for errors detected when using the schema to validate
175
        /// a source document.</para>
176
		/// </remarks>
177
		/// <param name="value">Supplied list.</param>
178
        public void SetErrorList(IList<XmlProcessingError> value)
179
        {
180
            reporter = new ErrorReporter(value);
181
            schemaManager.setErrorReporter(reporter);
182
        }
183

    
184
        /// <summary>
185
		/// Get list of errors as <code>IList&lt;XmlProcessingError&gt;</code>
186
        /// </summary>
187
        public IList<XmlProcessingError> GetErrorList()
188
        {
189
            if (reporter == null) {
190
                return new List<XmlProcessingError>();
191
            }
192
            return reporter.ErrorList;
193

    
194
        }
195

    
196

    
197
        /// <summary>Set the <c>ErrorReporter</c> to be used when validating instance documents as a user defined ErrorReporter.
198
        /// If this property is used then the ErrorList property and SetErrorList method is overriden </summary>
199
        /// <remarks>The <c>IErrorReporter</c> to be used</remarks>
200
        public IErrorReporter ErrorReporter {
201
            set {
202
                schemaManager.setErrorReporter(new ErrorReporterWrapper(value));                
203
            }
204
           
205
        }
206

    
207
    /// <summary>
208
    /// Compile a schema supplied as a <c>Stream</c>. The resulting schema components are added
209
    /// to the cache.
210
    /// </summary>
211
    /// <param name="input">A stream containing the source text of the schema. This method
212
    /// will consume the supplied stream. It is the caller's responsibility to close the stream
213
    /// after use.</param>
214
    /// <param name="baseUri">The base URI of the schema document, for resolving any references to other
215
    /// schema documents</param>        
216

    
217
    public void Compile(Stream input, Uri baseUri)
218
        {
219
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
220
            ss.setSystemId(baseUri.ToString());
221
			schemaManager.load (ss);
222
        }
223

    
224
        /// <summary>
225
        /// Compile a schema, retrieving the source using a URI. The resulting schema components are added
226
        /// to the cache.
227
        /// </summary>
228
        /// <remarks>
229
        /// The document located via the URI is parsed using the <c>System.Xml</c> parser.
230
        /// </remarks>
231
        /// <param name="uri">The URI identifying the location where the schema document can be
232
        /// found</param>
233

    
234
        public void Compile(Uri uri)
235
        {
236
            JStreamSource ss = new JStreamSource(uri.ToString());
237
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
238
            aug.setPleaseCloseAfterUse(true);
239
			schemaManager.load (aug);
240
        }
241

    
242
        /// <summary>
243
		/// Compile a schema, delivered using an <c>XmlReader</c>. The resulting schema components are added
244
        /// to the cache.
245
        /// </summary>
246
        /// <remarks>
247
        /// The <c>XmlReader</c> is responsible for parsing the document; this method builds a tree
248
        /// representation of the document (in an internal Saxon format) and compiles it.
249
        /// The <c>XmlReader</c> is used as supplied; it is the caller's responsibility to ensure that
250
        /// its settings are appropriate for parsing a schema document (for example, that entity references
251
        /// are expanded and whitespace is retained).
252
        /// </remarks>
253
		/// <param name="reader">The <c>XmlReader</c> (that is, the XML parser) used to supply the source schema document</param>
254

    
255
        public void Compile(XmlReader reader)
256
        {
257
            JPullProvider pp = new JDotNetPullProvider(reader);
258
            pp.setPipelineConfiguration(config.makePipelineConfiguration());
259
            // pp = new PullTracer(pp);  /* diagnostics */
260
            JPullSource ss = new JPullSource(pp);
261
            ss.setSystemId(reader.BaseURI);
262
			schemaManager.load (ss);
263
        }
264

    
265
        /// <summary>
266
		/// Compile a schema document, located at an <c>XdmNode</c>. This may be a document node whose
267
        /// child is an <c>xs:schema</c> element, or it may be
268
        /// the <c>xs:schema</c> element itself. The resulting schema components are added
269
        /// to the cache.
270
        /// </summary>
271
        /// <param name="node">The document node or the outermost element node of a schema document.</param>
272

    
273
        public void Compile(XdmNode node)
274
        {
275
            
276
            if (reporter == null)
277
            {
278
                reporter = new ErrorReporter(new List<XmlProcessingError>());
279

    
280
            }
281
            try
282
            {
283
                config.readInlineSchema((JNodeInfo)node.value, null, reporter);
284
            }
285
            catch (JSchemaException e)
286
            {
287
                throw new StaticError(e);
288
            }
289
        }
290

    
291
        /// <summary>
292
        /// Create a new <c>SchemaValidator</c>, which may be used for validating instance
293
        /// documents.
294
        /// </summary>
295
        /// <remarks>
296
        /// <para>The <c>SchemaValidator</c> uses the cache of schema components held by the
297
        /// <c>SchemaManager</c>. It may also add new components to this cache (for example,
298
        /// when the instance document references a schema using <c>xsi:schemaLocation</c>).
299
        /// It is also affected by changes to the schema cache that occur after the 
300
        /// <c>SchemaValidator</c> is created.</para>
301
        /// <para>When schema components are used for validating instance documents (or for compiling
302
        /// schema-aware queries and stylesheets) they are <i>sealed</i> to prevent subsequent modification.
303
        /// The modifications disallowed once a component is sealed include adding to the substitution group
304
        /// of an element declaration, adding subtypes derived by extension to an existing complex type, and
305
        /// use of <c>&lt;xs:redefine&gt;</c>.</para>
306
        /// </remarks>
307

    
308
        public SchemaValidator NewSchemaValidator()
309
        {
310
			return new SchemaValidator(schemaManager.newSchemaValidator(), processor);
311
        }
312

    
313
        /// <summary>
314
		/// Factory method to get an <c>AtomicType</c> object representing the atomic type with a given <c>QName</c>.
315
        /// </summary>
316
        /// <remarks>
317
		/// It is undefined whether two calls on this method supplying the same <c>QName</c> will return the same
318
        /// <c>XdmAtomicType</c> object instance.
319
        /// </remarks>
320
		/// <param name="qname">The <c>QName</c> of the required type</param>
321
        /// <returns>An <c>AtomicType</c> object representing this type if it is present in this schema (and is an
322
        /// atomic type); otherwise, null. </returns>
323

    
324
        public XdmAtomicType GetAtomicType(QName qname)
325
        {
326
			JSchemaType type = config.getSchemaType(qname.ToStructuredQName());
327
            if (type is JBuiltInAtomicType)
328
            {
329
                return XdmAtomicType.BuiltInAtomicType(qname);
330
            }
331
            else if (type is JAtomicType)
332
            {
333
                JItemTypeFactory factory = new JItemTypeFactory(processor.JProcessor);
334
                return new XdmAtomicType(factory.getAtomicType(qname.UnderlyingQName()));
335
            }
336
            else
337
            {
338
                return null;
339
            }
340
        }
341

    
342
    }
343

    
344
    /// <summary>
345
    /// A <c>SchemaValidator</c> is an object that is used for validating instance documents
346
    /// against a schema. The schema consists of the collection of schema components that are
347
    /// available within the schema cache maintained by the <c>SchemaManager</c>, together with
348
    /// any additional schema components located during the course of validation by means of an
349
    /// <c>xsl:schemaLocation</c> or <c>xsi:noNamespaceSchemaLocation</c> attribute within the
350
    /// instance document.
351
    /// </summary>
352
    /// <remarks>
353
    /// If validation fails, an exception is thrown. If validation succeeds, the validated
354
    /// document can optionally be written to a specified destination. This will be a copy of
355
    /// the original document, augmented with default values for absent elements and attributes,
356
    /// and carrying type annotations derived from the schema processing. Saxon does not deliver
357
    /// the full PSVI as described in the XML schema specifications, only the subset of the
358
    /// PSVI properties featured in the XDM data model.
359
    /// </remarks>    
360

    
361
    [Serializable]
362
    public class SchemaValidator
363
    {
364

    
365
        private JConfiguration config;
366
        private bool lax = false;
367
        private JSource source;
368
        private List<JSource> sources = new List<JSource>();
369
        private IList<ValidationFailure> errorList = null;
370
        private Processor processor = null;
371
        private JSchemaValidator schemaValidator;
372
        private JSchemaType documentElementType; 
373

    
374
        // internal constructor
375

    
376
        internal SchemaValidator(JSchemaValidator validator, Processor processor)
377
        {
378
            this.processor = processor;
379
            this.schemaValidator = validator;
380
            this.config = processor.Implementation;
381
        }
382

    
383
        /// <summary>
384
        /// The validation mode may be either strict or lax. The default is strict;
385
        /// this property is set to indicate that lax validation is required. With strict validation,
386
        /// validation fails if no element declaration can be located for the outermost element. With lax
387
        /// validation, the absence of an element declaration results in the content being considered valid.
388
        /// </summary>
389

    
390
        public bool IsLax
391
        {
392
            get { return schemaValidator.isLax(); }
393
            set { schemaValidator.setLax(value); }
394
        }
395

    
396
        /// <summary>
397
        /// This property defines whether the schema processor will recognize, and attempt to
398
        /// dereference, any <c>xsi:schemaLocation</c> and <c>xsi:noNamespaceSchemaLocation</c>
399
        /// attributes encountered in the instance document. The default value is true.
400
        /// </summary>
401

    
402
        public Boolean UseXsiSchemaLocation
403
        {
404
            get
405
            {
406
                return schemaValidator.isUseXsiSchemaLocation();
407
            }
408
            set
409
            {
410
                schemaValidator.setUseXsiSchemaLocation(value);
411
            }
412
        }
413

    
414

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

    
418
        public void SetValidityReporting(XmlDestination destination) {
419
            schemaValidator.setValidityReporting(destination.GetUnderlyingDestination());
420
        }
421

    
422

    
423

    
424
        /// <summary>Set the <c>InvalidityHandler</c> to be used when validating instance documents</summary>
425
        /// <param name="inHandler">the <c>InvalidityHandler</c> to be used</param>
426

    
427
        public void SetInvalidityHandler(IInvalidityHandler inHandler) {
428
            schemaValidator.setInvalidityHandler(new InvalidityHandlerWrapper(inHandler));
429
        }
430

    
431
        /// <summary>
432
        /// Add an instance document to the list of documents to be validated.
433
        /// </summary>
434
        /// <param name="source">Source document supplied as a <c>Stream</c></param>
435
        /// <param name="baseUri">Base URI of the source document</param>
436

    
437
        public void AddSource(Stream source, Uri baseUri) {
438
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(source));
439
            ss.setSystemId(baseUri.ToString());
440
            sources.Add(ss);
441
        }
442

    
443
        /// <summary>
444
        /// Add an instance document to the list of documents to be validated
445
        /// </summary>
446
        /// <param name="uri">URI of the source document</param>
447

    
448
        public void AddSource(Uri uri) {
449
            JStreamSource ss = new JStreamSource(uri.ToString());
450
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
451
            aug.setPleaseCloseAfterUse(true);
452
            sources.Add(aug);
453
        }
454

    
455
        /// <summary>
456
        /// Add an instance document to the list of documents to be validated
457
        /// </summary>
458
        /// <param name="reader">Source document supplied as an <c>XmlReader</c></param>
459

    
460
        public void AddSource(XmlReader reader) {
461
            JPullProvider pp = new JDotNetPullProvider(reader);
462
            JPipelineConfiguration pipe = config.makePipelineConfiguration();
463
            pipe.setUseXsiSchemaLocation(schemaValidator.isUseXsiSchemaLocation());
464
            pp.setPipelineConfiguration(pipe);
465
            // pp = new PullTracer(pp);  /* diagnostics */
466
            JPullSource psource = new JPullSource(pp);
467
            psource.setSystemId(reader.BaseURI);
468
            sources.Add(psource);
469
        }
470

    
471
        /// <summary>
472
        /// Add an instance document to the list of documents to be validated.
473
        /// </summary>
474
        /// <param name="source">Source document supplied as an <c>XdmNode</c> value</param>
475

    
476
        public void AddSource(XdmNode source) {
477
            sources.Add((JNodeInfo)source.value);
478
        }
479

    
480
        /// <summary>
481
		/// Supply the instance document to be validated in the form of a <c>Stream</c>
482
        /// </summary>
483
        /// <param name="source">A stream containing the XML document to be parsed
484
        /// and validated. This stream will be consumed by the validation process,
485
        /// but it will not be closed after use: that is the responsibility of the
486
        /// caller.</param>
487
        /// <param name="baseUri">The base URI to be used for resolving any relative
488
        /// references, for example a reference to an <c>xsi:schemaLocation</c></param>                  
489

    
490
        public void SetSource(Stream source, Uri baseUri)
491
        {
492
            JStreamSource ss = new JStreamSource(new JDotNetInputStream(source));
493
            ss.setSystemId(baseUri.ToString());
494
            this.source = ss;
495
            sources.Clear();
496
        }
497

    
498
        /// <summary>
499
		/// Supply the instance document to be validated in the form of a <c>Uri</c> reference
500
        /// </summary>
501
        /// <param name="uri">URI of the document to be validated</param>                  
502

    
503
        public void SetSource(Uri uri)
504
        {
505
            JStreamSource ss = new JStreamSource(uri.ToString());
506
            JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(ss);
507
            aug.setPleaseCloseAfterUse(true);
508
            this.source = aug;
509
            sources.Clear();
510
        }
511

    
512
        /// <summary>
513
		/// Supply the instance document to be validated, in the form of an <c>XmlReader</c>.
514
        /// </summary>
515
        /// <remarks>
516
		/// The <c>XmlReader</c> is responsible for parsing the document; this method validates it.
517
        /// </remarks>
518
        /// <param name="reader">The <c>XmlReader</c> used to read and parse the instance
519
        /// document being validated. This is used as supplied. For conformance, use of a
520
        /// plain <c>XmlTextReader</c> is discouraged, because it does not expand entity
521
        /// references. This may cause validation failures.
522
        /// </param>
523

    
524
        public void SetSource(XmlReader reader)
525
        {
526
            JPullProvider pp = new JDotNetPullProvider(reader);
527
            JPipelineConfiguration pipe = config.makePipelineConfiguration();
528
            pipe.setUseXsiSchemaLocation(schemaValidator.isUseXsiSchemaLocation());
529
            pp.setPipelineConfiguration(pipe);
530
            // pp = new PullTracer(pp);  /* diagnostics */
531
            JPullSource psource = new JPullSource(pp);
532
            psource.setSystemId(reader.BaseURI);
533
            this.source = psource;
534
            sources.Clear();
535
        }
536

    
537
        /// <summary>
538
		/// Supply the instance document to be validated in the form of an <c>XdmNode</c>.
539
        /// </summary>
540
        /// <remarks>
541
        /// <para>The supplied node must be either a document node or an element node.
542
        /// If an element node is supplied, then the subtree rooted at this element is
543
        /// validated as if it were a complete document: that is, it must not only conform
544
        /// to the structure required of that element, but any referential constraints
545
        /// (keyref, IDREF) must be satisfied within that subtree.
546
        /// </para>
547
        /// </remarks>
548
        /// <param name="source">The document or element node at the root of the tree
549
        /// to be validated</param>        
550

    
551
        public void SetSource(XdmNode source)
552
        {
553
            this.source = (JNodeInfo)source.value;
554
            sources.Clear();
555
        }
556

    
557
        /// <summary>
558
        /// Supply the destination to hold the validated document. If no destination
559
        /// is supplied, the validated document is discarded.
560
        /// </summary>
561
        /// <remarks>
562
        /// The destination differs from the source in that (a) default values of missing
563
        /// elements and attributes are supplied, and (b) the typed values of elements and
564
        /// attributes are available. However, typed values can only be accessed if the result
565
        /// is represented using the XDM data model, that is, if the destination is supplied
566
		/// as an <c>XdmDestination</c>.
567
        /// </remarks>
568
        /// <param name="destination">
569
        /// The destination to hold the validated document.
570
        /// </param>
571

    
572
        public void SetDestination(XmlDestination destination)
573
        {
574
            schemaValidator.setDestination(destination.GetUnderlyingDestination());
575
        }
576

    
577
        /// <summary>
578
        /// Close the destination, allowing resources to be released. Saxon calls this method
579
        /// when it has finished writing to the destination
580
        /// </summary>
581
        public void Close()
582
        {
583
            schemaValidator.close();
584
        }
585

    
586

    
587
        /// <summary>
588
        /// The name of the required top-level element of the document to be validated (that is, the
589
        /// name of the outermost element of the document).
590
        /// if no value is supplied, there is no constraint on the required type
591
        /// </summary>
592
        public QName DocumentElementName {
593

    
594
            get {
595
                net.sf.saxon.s9api.QName qname = schemaValidator.getDocumentElementName();
596
                return qname == null ? null : new QName(qname.getEQName()); }
597
            set { schemaValidator.setDocumentElementName(value.UnderlyingQName()); }
598

    
599
        }
600

    
601

    
602
        /// <summary>
603
        /// The name of the required type of the top-level element of the document to be validated.
604
        /// QName of the name of the required type of the document element, or null if no value has been set.
605
        /// If no value is supplied, there is no constrin on the required type
606
        /// </summary>
607
        public QName DocumentElementTypeName {
608
            get {
609

    
610
                net.sf.saxon.s9api.QName qtname = schemaValidator.getDocumentElementTypeName();
611
                return qtname == null ? null : new QName(qtname.getEQName());
612
            }
613
            set { schemaValidator.setDocumentElementTypeName(value.UnderlyingQName());
614
                documentElementType = config.getSchemaType(value.ToStructuredQName());
615
            }
616
        }
617

    
618
        internal JSchemaType DocumentElementType {
619

    
620
            get { return documentElementType; }
621
        }
622

    
623
        internal JSchemaValidator UnderlyingSchemaValidator
624
        {
625
            get
626
            {
627
                return schemaValidator;
628
            }
629
        }
630

    
631

    
632
        /// <summary>
633
        /// Set the value of a schema parameter (a parameter defined in the schema using the <c>saxon:param</c> extension)
634
        /// </summary>
635
        /// <param name="name">the name of the schema parameter, as a QName</param>
636
        /// <param name="value">the value of the schema  parameter, or null to clear a previously set value</param>
637
        public void SetParameter(QName name, XdmValue value) {
638
            try {
639
                schemaValidator.setParameter(name.UnderlyingQName(), value == null ? null : XdmValue.FromGroundedValueToJXdmValue(value.value));
640
            } catch (net.sf.saxon.s9api.SaxonApiUncheckedException ex) {
641
                throw new StaticError(ex);
642
            }
643
            
644
        }
645

    
646

    
647
        /// <summary>
648
        /// Get the value that has set for a schema processor (a parameter defined in the schema using the <c>saxon:param</c>
649
        /// extension)
650
        /// </summary>
651
        /// <param name="name">the parameter whose name is required</param>
652
        /// <returns>the value that has been set for the parameter, or the EmptySequence if no value has been set</returns>
653
        public XdmValue GetParameter(QName name)
654
        {
655
            net.sf.saxon.s9api.XdmValue value = schemaValidator.getParameter(name.UnderlyingQName());
656
            return value == null ? null : XdmValue.Wrap(value.getUnderlyingValue());
657
        }
658
         
659

    
660

    
661
        /// <summary>
662
        /// Ask and set whether attribute defaults defined in a schema are to be expanded or not
663
        /// (by default, fixed and default attribute values are expaned, that is, they are inserted) into
664
        /// the document during validation as if they were present in the instance being validated)
665
        /// </summary>
666
        public bool ExpendAttributeDefaults {
667
            get { return schemaValidator.isExpandAttributeDefaults(); }
668
            set { schemaValidator.setExpandAttributeDefaults(value); }
669
        }
670

    
671
        /// <summary>
672
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
673
        /// the processor will then populate the list with error information obtained during
674
		/// the schema compilation. Each error will be included as an object of type <c>StaticError</c>.
675
        /// If no error list is supplied by the caller, error information will be written to
676
        /// the standard error stream.
677
        /// </summary>
678
        /// <remarks>
679
		/// <para>By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
680
        /// intercept error conditions as they occur.</para>
681
        /// <para>Note that this error list is used only for errors detected while 
682
        /// using the schema to validate a source document. It is not used to report errors
683
        /// in the schema itself.</para>
684
        /// </remarks>
685

    
686
        public IList<ValidationFailure> ErrorList
687
        {
688
            set
689
            {
690
                errorList = value;
691
                schemaValidator.setInvalidityHandler(new InvalidityGatherer(errorList));
692
                
693
            }
694
            get
695
            {
696
                return errorList;
697
            }
698
        }
699
			
700
			
701

    
702

    
703
        /// <summary>
704
        /// Run the validation of the supplied source document, optionally
705
        /// writing the validated document to the supplied destination.
706
        /// </summary>
707

    
708
        public void Run()
709
        {
710

    
711
            if (source == null)
712
            {
713
                if (sources.Count == 0) {
714
                    throw new StaticError(new net.sf.saxon.trans.XPathException("No source(s) set for the SchemaValidator"));
715
                }
716
                java.util.List iter = new java.util.ArrayList();
717
                foreach (JSource src in sources) {
718
                    iter.add(src);
719
                }
720
                try
721
                {
722
                    schemaValidator.validateMultiple(iter);
723
                }
724
                catch (net.sf.saxon.s9api.SaxonApiException ex) {
725
                    throw new StaticError(ex);
726
                }
727
            }
728
            else
729
            {
730
                JAugmentedSource aug = JAugmentedSource.makeAugmentedSource(source);
731
                aug.setSchemaValidationMode(lax ? JValidation.LAX : JValidation.STRICT);
732
                try {
733
                    schemaValidator.validate(aug);
734
                }
735
                catch (net.sf.saxon.s9api.SaxonApiException ex)
736
            {
737
                throw new StaticError(ex);
738
            }
739
        }
740
                
741
        }
742

    
743
    }
744

    
745

    
746
    /// <summary>
747
	/// The <c>SchemaResolver</c> is a user-supplied class used for resolving references to
748
    /// schema documents. It applies to references from one schema document to another
749
    /// appearing in <c>xs:import</c>, <c>xs:include</c>, and <c>xs:redefine</c>; to
750
    /// references from an instance document to a schema in <c>xsi:schemaLocation</c> and
751
    /// <c>xsi:noNamespaceSchemaLocation</c>, to <c>xsl:import-schema</c> in XSLT, and to
752
    /// the <c>import schema</c> declaration in XQuery.
753
    /// </summary>
754

    
755
    public interface SchemaResolver
756
    {
757

    
758
        /// <summary>
759
        /// Given a target namespace and a set of location hints, return a set of schema documents.
760
        /// </summary>
761
        /// <param name="targetNamespace">The target namespace of the required schema components</param>
762
        /// <param name="baseUri">The base URI of the module containing the reference to a schema document
763
        /// declaration</param>
764
        /// <param name="locationHints">The sequence of URIs (if any) listed as location hints.
765
        /// In most cases there will only be one; but the <c>import schema</c> declaration in
766
        /// XQuery permits several.</param>
767
		/// <returns>A set of absolute URIs identifying the schema documents to be loaded. There is no requirement
768
        /// that these correspond one-to-one with the URIs defined in the <c>locationHints</c>. The 
769
        /// returned URIs will be dereferenced by calling the <c>GetEntity</c> method.
770
        /// </returns>
771

    
772
        /**public**/ Uri[] GetSchemaDocuments(String targetNamespace, Uri baseUri, String[] locationHints);
773

    
774
        /// <summary>
775
		/// Dereference a URI returned by <c>GetSchemaDocuments</c> to retrieve a <c>Stream</c> containing
776
        /// the actual XML schema document.
777
        /// </summary>
778
        /// <param name="absoluteUri">A URI returned by the <code>GetSchemaDocuments</code> method.</param>
779
		/// <returns>Either a <c>Stream</c> or a <c>String</c> containing the schema text. 
780
		/// The supplied URI will be used as the base URI of the schema document.</returns>
781

    
782
        /**public**/ Object GetEntity(Uri absoluteUri);
783

    
784
    }
785

    
786

    
787

    
788
    /// <summary>
789
	/// internal class that wraps a (.NET) QueryResolver to create a (Java) SchemaURIResolver
790
    /// </summary>
791

    
792
    internal class DotNetSchemaURIResolver : net.sf.saxon.lib.SchemaURIResolver
793
    {
794

    
795
        internal SchemaResolver resolver;
796
        internal JConfiguration config;
797

    
798
		/// <summary>
799
		/// Initializes a new instance of the <see cref="Saxon.Api.DotNetSchemaURIResolver"/> class.
800
		/// </summary>
801
		/// <param name="resolver">Resolver.</param>
802
        public DotNetSchemaURIResolver(SchemaResolver resolver)
803
        {
804
            this.resolver = resolver;
805
        }
806

    
807
        public void setConfiguration(JConfiguration config)
808
        {
809
            this.config = config;
810
        }
811

    
812
		/// <summary>
813
		/// Resolve the specified targetNamespace, baseURI and locations.
814
		/// </summary>
815
		/// <param name="targetNamespace">Target namespace.</param>
816
		/// <param name="baseURI">BaseURI.</param>
817
		/// <param name="locations">Locations.</param>
818
        public JSource[] resolve(String targetNamespace, String baseURI, String[] locations)
819
        {
820
			if (config.isSchemaAvailable(targetNamespace) && !(java.lang.Boolean.valueOf(((java.lang.Object)config.getConfigurationProperty(JFeatureKeys.MULTIPLE_SCHEMA_IMPORTS)).toString()).booleanValue()))
821
            {
822
                return new JSource[0];
823
            }
824
            Uri baseU = (baseURI == null ? null : new Uri(baseURI));
825
            Uri[] modules = resolver.GetSchemaDocuments(targetNamespace, baseU, locations);
826
            JStreamSource[] ss = new JStreamSource[modules.Length];
827
            for (int i = 0; i < ss.Length; i++)
828
            {
829
                ss[i] = new JStreamSource();
830
                ss[i].setSystemId(modules[i].ToString());
831
                Object doc = resolver.GetEntity(modules[i]);
832
                if (doc is Stream)
833
                {
834
                    ss[i].setInputStream(new JDotNetInputStream((Stream)doc));
835
                }
836
                else if (doc is String)
837
                {
838
                    ss[i].setReader(new JDotNetReader(new StringReader((String)doc)));
839
                }
840
                else
841
                {
842
                    throw new ArgumentException("Invalid response from GetEntity()");
843
                }
844
            }
845
            return ss;
846
        }
847
    }
848

    
849

    
850

    
851

    
852

    
853

    
854
}
855

    
856
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
857
// Copyright (c) 2020 Saxonica Limited.
858
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
859
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
860
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
861
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(7-7/11)