Project

Profile

Help

Revision b0b00ab2

Added by O'Neil Delpratt over 8 years ago

Saxon maintenance release 9.4.0.7

View differences:

tags/9.4.0.7/hen/csource/api/Saxon.Api/Configuration.cs
1
´╗┐using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections;
5
using System.Collections.Specialized;
6
using System.Reflection;
7
using System.Globalization;
8
using javax.xml.transform;
9
using javax.xml.transform.stream;
10
using JClass = java.lang.Class;
11
using JBoolean = java.lang.Boolean;
12
using JResult = javax.xml.transform.Result;
13
using JSource = javax.xml.transform.Source;
14
using JProperties = java.util.Properties;
15
using JBufferedReader = java.io.BufferedReader;
16
using JStringReader = java.io.StringReader;
17
using JConfiguration = net.sf.saxon.Configuration;
18
using JFeatureKeys = net.sf.saxon.lib.FeatureKeys;
19
using JVersion = net.sf.saxon.Version;
20
using JDocumentWrapper = net.sf.saxon.dotnet.DocumentWrapper;
21
using JDotNetObjectModel = net.sf.saxon.dotnet.DotNetObjectModel;
22
using JNodeInfo = net.sf.saxon.om.NodeInfo;
23
using JDocumentInfo = net.sf.saxon.om.DocumentInfo;
24
//using JSingletonItem = net.sf.saxon.value.SingletonItem;
25
using JValue = net.sf.saxon.value.Value;
26
using JValueRepresentation = net.sf.saxon.om.ValueRepresentation;
27
using JPipelineConfiguration = net.sf.saxon.@event.PipelineConfiguration;
28
using JXPathContext = net.sf.saxon.expr.XPathContext;
29
using JSequenceExtent = net.sf.saxon.value.SequenceExtent;
30
using AugmentedSource = net.sf.saxon.lib.AugmentedSource;
31
using StructuredQName = net.sf.saxon.om.StructuredQName;
32
using Whitespace = net.sf.saxon.value.Whitespace;
33
using StaticQueryContext = net.sf.saxon.query.StaticQueryContext;
34
using JReceiver = net.sf.saxon.@event.Receiver;
35
using JTreeReceiver = net.sf.saxon.@event.TreeReceiver;
36
using JNamespaceReducer = net.sf.saxon.@event.NamespaceReducer;
37
using JValidation = net.sf.saxon.lib.Validation;
38
using JXPathException = net.sf.saxon.trans.XPathException;
39
using net.sf.saxon.om;
40
using net.sf.saxon.pull;
41
using net.sf.saxon.dotnet;
42

  
43

  
44
namespace Saxon.Api
45
{
46

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

  
55
    [Serializable]
56
    public class Processor 
57
    {
58

  
59
        //Transformation data variables
60
        internal JConfiguration config;
61
        private SchemaManager schemaManager = null;
62

  
63
        /// <summary>
64
        /// Create a new Processor. This Processor will have capabilities that depend on the version
65
        /// of the software that has been loaded, and on the features that have been licensed.
66
        /// </summary>
67

  
68
        public Processor()
69
        {
70
            config = JConfiguration.newConfiguration();
71
            config.registerExternalObjectModel(new DotNetObjectModelDefinition());
72
            config.setProcessor(this);
73
        }
74

  
75
        /// <summary>
76
        /// Create a Processor.
77
        /// </summary>
78
        /// <param name="licensedEdition">Set to true if the Processor is to use a licensed edition of Saxon
79
        /// (that is, Saxon-PE or Saxon-EE). If true, the Processor will attempt to enable the capabilities
80
        /// of the licensed edition of Saxon, according to the version of the software that is loaded, and will
81
        /// verify the license key. If false, the Processor will load a default Configuration that gives restricted
82
        /// capability and does not require a license, regardless of which version of the software is actually being run.</param>
83

  
84
        public Processor(bool licensedEdition) 
85
            // newline needed by documentation stylesheet
86
            : this(licensedEdition, false) { }
87

  
88
        /// <summary>
89
        /// Create a Processor.
90
        /// </summary>
91
        /// <param name="licensedEdition">Set to true if the Processor is to use a licensed edition of Saxon
92
        /// (that is, Saxon-PE or Saxon-EE). If true, the Processor will attempt to enable the capabilities
93
        /// of the licensed edition of Saxon, according to the version of the software that is loaded, and will
94
        /// verify the license key. If false, the Processor will load a default Configuration that gives restricted
95
        /// capability and does not require a license, regardless of which version of the software is actually being run.</param>
96
        /// <param name="loadLocally">This option has no effect at this release.</param>
97

  
98
        public Processor(bool licensedEdition, bool loadLocally)
99
        {
100
            if (licensedEdition)
101
            {
102
                config = JConfiguration.newConfiguration();
103
                schemaManager = new SchemaManager(config);
104
            }
105
            else
106
            {
107
                config = new JConfiguration();
108
            }
109
            config.registerExternalObjectModel(new DotNetObjectModelDefinition());
110
            config.setProcessor(this);
111
        }
112

  
113
        /// <summary>
114
        /// Create a Processor, based on configuration information supplied in a configuration file.
115
        /// </summary>
116
        /// <remarks>
117
        /// Not fully supported in this release: for experimental use only.
118
        /// </remarks>
119
        /// <param name="configurationFile">A stream holding the text of the XML configuration file. Details of the file format
120
        /// can be found in the Saxon documentation.</param>
121
        /// 
122

  
123
        public Processor(Stream configurationFile)
124
        {
125
            StreamSource ss = new StreamSource(new DotNetInputStream(configurationFile));
126
            config = JConfiguration.readConfiguration(ss);
127
            config.registerExternalObjectModel(new DotNetObjectModelDefinition());
128
            config.setProcessor(this);
129
        }
130

  
131

  
132
        /// <summary>
133
        /// Get the full name of the Saxon product version implemented by this Processor
134
        /// </summary>
135

  
136
        public string ProductTitle
137
        {
138
            get { return JVersion.getProductTitle(); }
139
        }
140

  
141
        /// <summary>
142
        /// Get the Saxon product version number (for example, "9.2.0.2")
143
        /// </summary>
144

  
145
        public string ProductVersion
146
        {
147
            get { return JVersion.getProductVersion(); }
148
        }
149

  
150
        /// <summary>
151
        /// Get the Saxon product edition (for example, "EE" for Enterprise Edition)
152
        /// </summary>
153
        /// 
154

  
155
        public string Edition
156
        {
157
            get { return config.getEditionCode(); }
158
        }
159

  
160

  
161
        /// <summary>
162
        /// Indicates whether the Processor is schema-aware. In Saxon 9.2, returns true if using Saxon
163
        /// Enterprise Edition.
164
        /// </summary>
165
        /// <remarks>
166
        /// Deprecated since Saxon 9.2; schema-awareness is not directly a property of a Processor any more.
167
        /// Use the Edition property to determine which Saxon edition is in use.
168
        /// </remarks>
169

  
170
        public bool IsSchemaAware
171
        {
172
            get { return config.getEditionCode() == "EE"; }
173
        }
174

  
175
        /// <summary>
176
        /// Gets the SchemaManager for the Processor. Returns null
177
        /// if the Processor is not schema-aware.
178
        /// </summary>
179

  
180
        public SchemaManager SchemaManager
181
        {
182
            get { return schemaManager; }
183
        }
184

  
185
        /// <summary>
186
        /// An XmlResolver, which will be used while compiling and running queries, 
187
        /// XPath expressions, and stylesheets, if no other XmlResolver is nominated
188
        /// </summary>
189
        /// <remarks>
190
        /// <para>By default an <c>XmlUrlResolver</c> is used. This means that the responsibility
191
        /// for resolving and dereferencing URIs rests with the .NET platform, not with the
192
        /// GNU Classpath.</para>
193
        /// <para>When Saxon invokes a user-written <c>XmlResolver</c>, the <c>GetEntity</c> method
194
        /// may return any of: a <c>System.IO.Stream</c>; a <c>System.IO.TextReader</c>; or a
195
        /// <c>java.xml.transform.Source</c>.</para>
196
        /// </remarks>
197

  
198
        public XmlResolver XmlResolver
199
        {
200
            get
201
            {
202
                return ((DotNetURIResolver)config.getURIResolver()).getXmlResolver();
203
            }
204
            set
205
            {
206
                config.setURIResolver(new DotNetURIResolver(value));
207
            }
208
        }
209

  
210
        /// <summary>
211
        /// Create a new <c>DocumentBuilder</c>, which may be used to build XDM documents from
212
        /// a variety of sources.
213
        /// </summary>
214
        /// <returns>A new <c>DocumentBuilder</c></returns>
215

  
216
        public DocumentBuilder NewDocumentBuilder()
217
        {
218
            DocumentBuilder builder = new DocumentBuilder(this);
219
            builder.XmlResolver = XmlResolver;
220
            return builder;
221
        }
222

  
223
        /// <summary>
224
        /// Create a new XQueryCompiler, which may be used to compile XQuery queries.
225
        /// </summary>
226
        /// <remarks>
227
        /// The returned XQueryCompiler retains a live link to the Processor, and
228
        /// may be affected by subsequent changes to the Processor.
229
        /// </remarks>
230
        /// <returns>A new XQueryCompiler</returns>
231

  
232
        public XQueryCompiler NewXQueryCompiler()
233
        {
234
            return new XQueryCompiler(this);
235
        }
236

  
237
        /// <summary>
238
        /// Create a new XsltCompiler, which may be used to compile XSLT stylesheets.
239
        /// </summary>
240
        /// <remarks>
241
        /// The returned XsltCompiler retains a live link to the Processor, and
242
        /// may be affected by subsequent changes to the Processor.
243
        /// </remarks>
244
        /// <returns>A new XsltCompiler</returns>
245

  
246
        public XsltCompiler NewXsltCompiler()
247
        {
248
            return new XsltCompiler(this);
249
        }
250

  
251
        /// <summary>
252
        /// Create a new XPathCompiler, which may be used to compile XPath expressions.
253
        /// </summary>
254
        /// <remarks>
255
        /// The returned XPathCompiler retains a live link to the Processor, and
256
        /// may be affected by subsequent changes to the Processor.
257
        /// </remarks>
258
        /// <returns>A new XPathCompiler</returns>
259

  
260
        public XPathCompiler NewXPathCompiler()
261
        {
262
            return new XPathCompiler(this);
263
        }
264

  
265
        /// <summary>
266
        /// The XML version used in this <c>Processor</c> (for example, this determines what characters
267
        /// are permitted in a name)
268
        /// </summary>
269
        /// <remarks>
270
        /// The value must be 1.0 or 1.1, as a <c>decimal</c>. The default version is currently 1.0, but may
271
        /// change in the future.
272
        /// </remarks>
273

  
274
        public decimal XmlVersion
275
        {
276
            get
277
            {
278
                return (config.getXMLVersion() == JConfiguration.XML10 ? 1.0m : 1.1m);
279
            }
280
            set
281
            {
282
                if (value == 1.0m)
283
                {
284
                    config.setXMLVersion(JConfiguration.XML10);
285
                }
286
                else if (value == 1.1m)
287
                {
288
                    config.setXMLVersion(JConfiguration.XML11);
289
                }
290
                else
291
                {
292
                    throw new ArgumentException("Invalid XML version: " + value);
293
                }
294
            }
295
        }
296

  
297
        /// <summary>
298
        /// Register a named collection. A collection is identified by a URI (the collection URI),
299
        /// and its content is represented by an <c>IEnumerable</c> that enumerates the contents
300
        /// of the collection. The values delivered by this enumeration are Uri values, which 
301
        /// can be mapped to nodes using the registered <c>XmlResolver</c>.
302
        /// </summary>
303
        /// <param name="collectionUri">The URI used to identify the collection in a call
304
        /// of the XPath <c>collection()</c> function. The default collection is registered
305
        /// by supplying null as the value of this argument (this is the collection returned
306
        /// when the XPath <c>collection()</c> function is called with no arguments).</param> 
307
        /// <param name="contents">An enumerable object that represents the contents of the
308
        /// collection, as a sequence of document URIs. The enumerator returned by this
309
        /// IEnumerable object must return instances of the Uri class.</param>
310
        /// <remarks>
311
        /// <para>Collections should be stable: that is, two calls to retrieve the same collection URI
312
        /// should return the same sequence of document URIs. This requirement is imposed by the
313
        /// W3C specifications, but in the case of a user-defined collection it is not enforced by
314
        /// the Saxon product.</para>
315
        /// <para>A collection may be "unregistered" by providing null as the value of the
316
        /// contents argument. A collection may be replaced by specifying the URI of an existing
317
        /// collection.</para>
318
        /// <para>Collections registered with a processor are available to all queries and stylesheets
319
        /// running under the control of that processor. Collections should not normally be registered
320
        /// while queries and transformations are in progress.</para>
321
        /// </remarks>
322
        /// 
323

  
324
        public void RegisterCollection(Uri collectionUri, IEnumerable contents)
325
        {
326
            String u = (collectionUri == null ? null : collectionUri.ToString());
327
            DotNetCollectionURIResolver resolver =
328
                (DotNetCollectionURIResolver)config.getCollectionURIResolver();
329
            resolver.registerCollection(u, contents);
330
        }
331

  
332
        /// <summary>
333
        /// Register an extension function with the Processor
334
        /// </summary>
335
        /// <param name="function">
336
        /// An object that defines the extension function, including its name, arity, arguments types, and
337
        /// a reference to the class that implements the extension function call.
338
        /// </param>
339

  
340
        public void RegisterExtensionFunction(ExtensionFunctionDefinition function)
341
        {
342
            WrappedExtensionFunctionDefinition f = new WrappedExtensionFunctionDefinition(function);
343
            config.registerExtensionFunction(f);
344
        }
345

  
346
        /// <summary>
347
        /// Copy an XdmValue to an XmlDestination
348
        /// </summary>
349
        /// <remarks>
350
        /// This method can be used to copy any kind of <c>XdmValue</c> to any kind
351
        /// of <c>XdmDestination</c>. The supplied <c>XdmValue</c> is first converted
352
        /// to an XML document according to the rules of the XSLT/XQuery serialization
353
        /// specification (for example, if the <c>XdmValue</c> is a sequence of atomic
354
        /// values, they will be turned in a text node in which the values are converted
355
        /// to strings and separated by single spaces). The resulting document is then
356
        /// written to the supplied <c>XmlDestination</c>.</remarks>
357
        /// <param name="sequence">The value to be written</param>
358
        /// <param name="destination">The destination to which the value should be written</param>
359
        /// 
360

  
361
        public void WriteXdmValue(XdmValue sequence, XmlDestination destination)
362
        {
363
            try
364
            {
365
                JPipelineConfiguration pipe = config.makePipelineConfiguration();
366
                JResult result = destination.GetResult(pipe);
367
                JReceiver r = config.getSerializerFactory().getReceiver(result,
368
                    pipe, destination.GetOutputProperties());
369
                r = new JNamespaceReducer(r);
370
                JTreeReceiver tree = new JTreeReceiver(r);
371
                tree.open();
372
                tree.startDocument(0);
373
                foreach (XdmItem it in sequence)
374
                {
375
                    tree.append((Item)it.Unwrap(), 0, JNodeInfo.__Fields.ALL_NAMESPACES);
376
                }
377
                tree.endDocument();
378
                tree.close();
379
            } catch(JXPathException err) {
380
                throw new DynamicError(err);
381
            }
382
        }
383

  
384

  
385
        /// <summary>
386
        /// The underlying Configuration object in the Saxon implementation
387
        /// </summary>
388
        /// <remarks>
389
        /// <para>This property provides access to internal methods in the Saxon engine that are
390
        /// not specifically exposed in the .NET API. In general these methods should be
391
        /// considered to be less stable than the classes in the Saxon.Api namespace.</para> 
392
        /// <para>The internal methods follow
393
        /// Java naming conventions rather than .NET conventions.</para>
394
        /// <para>Information about the returned object (and the objects it provides access to)
395
        /// is included in the Saxon JavaDoc docmentation, available 
396
        /// <link href="http://www.saxonica.com/documentation/javadoc/index.html">online</link>.
397
        /// </para>
398
        /// </remarks>
399

  
400
        public net.sf.saxon.Configuration Implementation
401
        {
402
            get { return config; }
403
        }
404

  
405
        /// <summary>
406
        /// Set a configuration property
407
        /// </summary>
408
        /// <remarks>
409
        /// <para>This method provides the ability to set named properties of the configuration.
410
        /// The property names are set as strings, whose values can be found in the Java
411
        /// class <c>net.sf.saxon.FeatureKeys</c>. The property values are always strings. 
412
        /// Properties whose values are other types are not available via this interface:
413
        /// however all properties have an effective equivalent whose value is a string.
414
        /// Note that on/off properties are set using the strings "true" and "false".</para>
415
        /// <para><i>Method added in Saxon 9.1</i></para>
416
        /// </remarks>
417
        /// <param name="name">The property name</param>
418
        /// <param name="value">The property value</param>
419

  
420
        public void SetProperty(String name, String value)
421
        {
422
            config.setConfigurationProperty(name, value);
423
        }
424

  
425
        /// <summary>
426
        /// Get the value of a configuration property
427
        /// </summary>
428
        /// <remarks>
429
        /// <para>This method provides the ability to get named properties of the configuration.
430
        /// The property names are supplied as strings, whose values can be found in the Java
431
        /// class <c>net.sf.saxon.FeatureKeys</c>. The property values are always returned as strings. 
432
        /// Properties whose values are other types are returned by converting the value to a string.
433
        /// Note that on/off properties are returned using the strings "true" and "false".</para>
434
        /// <para><i>Method added in Saxon 9.1</i></para>
435
        /// </remarks>
436
        /// <param name="name">The property name</param>
437
        /// <returns>The property value, as a string; or null if the property is unset.</returns>
438

  
439
        public String GetProperty(String name)
440
        {
441
            Object obj = config.getConfigurationProperty(name);
442
            return (obj == null ? null : obj.ToString());
443
        }
444

  
445
    }
446

  
447
    /// <summary>
448
    /// The <c>DocumentBuilder</c> class enables XDM documents to be built from various sources.
449
    /// The class is always instantiated using the <c>NewDocumentBuilder</c> method
450
    /// on the <c>Processor</c> object.
451
    /// </summary>
452

  
453
    [Serializable]
454
    public class DocumentBuilder
455
    {
456

  
457
        private Processor processor;
458
        private JConfiguration config;
459
        private XmlResolver xmlResolver;
460
        private SchemaValidationMode validation;
461
        private bool dtdValidation;
462
        private bool lineNumbering;
463
        private WhitespacePolicy whitespacePolicy;
464
        private Uri baseUri;
465
        private QName topLevelElement;
466
        private TreeModel treeModel = TreeModel.Unspecified;
467

  
468
        internal DocumentBuilder(Processor processor)
469
        {
470
            this.processor = processor;
471
            this.config = processor.Implementation;
472
            this.xmlResolver = new XmlUrlResolver();
473
        }
474

  
475
        /// <summary>
476
        /// An XmlResolver, which will be used to resolve URIs of documents being loaded
477
        /// and of references to external entities within those documents (including any external DTD).
478
        /// </summary>
479
        /// <remarks>
480
        /// <para>By default an <c>XmlUrlResolver</c> is used. This means that the responsibility
481
        /// for resolving and dereferencing URIs rests with the .NET platform (and not with the
482
        /// GNU Classpath).</para>
483
        /// <para>When Saxon invokes a user-written <c>XmlResolver</c>, the <c>GetEntity</c> method
484
        /// may return any of: a <c>System.IO.Stream</c>; a <c>System.IO.TextReader</c>; or a
485
        /// <c>java.xml.transform.Source</c>. However, if the <c>XmlResolver</c> is called
486
        /// by the XML parser to resolve external entity references, then it must return an 
487
        /// instance of <c>System.IO.Stream</c>.</para>
488
        /// </remarks>
489

  
490
        public XmlResolver XmlResolver
491
        {
492
            get
493
            {
494
                return xmlResolver;
495
            }
496
            set
497
            {
498
                xmlResolver = value;
499
            }
500
        }
501

  
502
        /// <summary>
503
        /// Determines whether line numbering is enabled for documents loaded using this
504
        /// <c>DocumentBuilder</c>.
505
        /// </summary>
506
        /// <remarks>
507
        /// <para>By default, line numbering is disabled.</para>
508
        /// <para>Line numbering is not available for all kinds of source: in particular,
509
        /// it is not available when loading from an existing XmlDocument.</para>
510
        /// <para>The resulting line numbers are accessible to applications using the
511
        /// extension function saxon:line-number() applied to a node.</para>  
512
        /// <para>Line numbers are maintained only for element nodes; the line number
513
        /// returned for any other node will be that of the most recent element.</para> 
514
        /// </remarks>
515

  
516
        public bool IsLineNumbering
517
        {
518
            get
519
            {
520
                return lineNumbering;
521
            }
522
            set
523
            {
524
                lineNumbering = value;
525
            }
526
        }
527

  
528
        /// <summary>
529
        /// Determines whether schema validation is applied to documents loaded using this
530
        /// <c>DocumentBuilder</c>, and if so, whether it is strict or lax.
531
        /// </summary>
532
        /// <remarks>
533
        /// <para>By default, no schema validation takes place.</para>
534
        /// <para>This option requires the schema-aware version of the Saxon product (Saxon-SA).</para>
535
        /// </remarks>
536

  
537
        public SchemaValidationMode SchemaValidationMode
538
        {
539
            get
540
            {
541
                return validation;
542
            }
543
            set
544
            {
545
                validation = value;
546
            }
547
        }
548

  
549
        /// <summary>
550
        /// The required name of the top level element in a document instance being validated
551
        /// against a schema.
552
        /// </summary>
553
        /// <remarks>
554
        /// <para>If this property is set, and if schema validation is requested, then validation will
555
        /// fail unless the outermost element of the document has the required name.</para>
556
        /// <para>This option requires the schema-aware version of the Saxon product (Saxon-SA).</para>
557
        /// </remarks> 
558

  
559
        public QName TopLevelElementName
560
        {
561
            get
562
            {
563
                return topLevelElement;
564
            }
565
            set
566
            {
567
                topLevelElement = value;
568
            }
569
        }
570

  
571
        /// <summary>
572
        /// Determines whether DTD validation is applied to documents loaded using this
573
        /// <c>DocumentBuilder</c>.
574
        /// </summary>
575
        /// <remarks>
576
        ///
577
        /// <para>By default, no DTD validation takes place.</para>
578
        /// 
579
        /// </remarks>
580

  
581
        public bool DtdValidation
582
        {
583
            get
584
            {
585
                return dtdValidation;
586
            }
587
            set
588
            {
589
                dtdValidation = value;
590
            }
591
        }
592

  
593
        /// <summary>
594
        /// Determines the whitespace stripping policy applied when loading a document
595
        /// using this <c>DocumentBuilder</c>.
596
        /// </summary>
597
        /// <remarks>
598
        /// <para>By default, whitespace text nodes appearing in element-only content
599
        /// are stripped, and all other whitespace text nodes are retained.</para>
600
        /// </remarks>
601

  
602
        public WhitespacePolicy WhitespacePolicy
603
        {
604
            get
605
            {
606
                return whitespacePolicy;
607
            }
608
            set
609
            {
610
                whitespacePolicy = value;
611
            }
612
        }
613

  
614
        ///<summary>
615
        /// The Tree Model implementation to be used for the constructed document. By default
616
        /// the TinyTree is used. The main reason for using the LinkedTree alternative is if
617
        /// updating is required (the TinyTree is not updateable).
618
        ///</summary>
619

  
620
        public TreeModel TreeModel
621
        {
622
            get
623
            {
624
                return treeModel;
625
            }
626
            set
627
            {
628
                treeModel = value;
629
            }
630
        }
631

  
632
        /// <summary>
633
        /// The base URI of a document loaded using this <c>DocumentBuilder</c>.
634
        /// This is used for resolving any relative URIs appearing
635
        /// within the document, for example in references to DTDs and external entities.
636
        /// </summary>
637
        /// <remarks>
638
        /// This information is required when the document is loaded from a source that does not
639
        /// provide an intrinsic URI, notably when loading from a Stream or a TextReader.
640
        /// </remarks>
641

  
642

  
643
        public Uri BaseUri
644
        {
645
            get { return baseUri; }
646
            set { baseUri = value; }
647
        }
648

  
649
        /// <summary>
650
        /// Load an XML document, retrieving it via a URI.
651
        /// </summary>
652
        /// <remarks>
653
        /// <para>Note that the type <c>Uri</c> requires an absolute URI.</para>
654
        /// <para>The URI is dereferenced using the registered <c>XmlResolver</c>.</para>
655
        /// <para>This method takes no account of any fragment part in the URI.</para>
656
        /// <para>The <c>role</c> passed to the <c>GetEntity</c> method of the <c>XmlResolver</c> 
657
        /// is "application/xml", and the required return type is <c>System.IO.Stream</c>.</para>
658
        /// <para>The document located via the URI is parsed using the <c>System.Xml</c> parser.</para>
659
        /// <para>Note that the Microsoft <c>System.Xml</c> parser does not report whether attributes are
660
        /// defined in the DTD as being of type <c>ID</c> and <c>IDREF</c>. This is true whether or not
661
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
662
        /// <c>id()</c> and <c>idref()</c> functions.</para>
663
        /// </remarks>
664
        /// <param name="uri">The URI identifying the location where the document can be
665
        /// found. This will also be used as the base URI of the document (regardless
666
        /// of the setting of the <c>BaseUri</c> property).</param>
667
        /// <returns>An <c>XdmNode</c>. This will be
668
        ///  the document node at the root of the tree of the resulting in-memory document. 
669
        /// </returns>
670

  
671
        public XdmNode Build(Uri uri)
672
        {
673
            Object obj = XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
674
            if (obj is Stream)
675
            {
676
                try
677
                {
678
                    return Build((Stream)obj, uri);
679
                }
680
                finally
681
                {
682
                    ((Stream)obj).Close();
683
                }
684
            }
685
            else
686
            {
687
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
688
            }
689
        }
690

  
691
        /// <summary>
692
        /// Load an XML document supplied as raw (lexical) XML on a Stream.
693
        /// </summary>
694
        /// <remarks>
695
        /// <para>The document is parsed using the Microsoft <c>System.Xml</c> parser if the
696
        /// "http://saxon.sf.net/feature/preferJaxpParser" property on the <c>Processor</c> is set to false;
697
        /// otherwise it is parsed using the Apache Xerces XML parser.</para>
698
        /// <para>Before calling this method, the <c>BaseUri</c> property must be set to identify the
699
        /// base URI of this document, used for resolving any relative URIs contained within it.</para>
700
        /// <para>Note that the Microsoft <c>System.Xml</c> parser does not report whether attributes are
701
        /// defined in the DTD as being of type <c>ID</c> and <c>IDREF</c>. This is true whether or not
702
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
703
        /// <c>id()</c> and <c>idref()</c> functions.</para>         
704
        /// </remarks>
705
        /// <param name="input">The Stream containing the XML source to be parsed</param>
706
        /// <returns>An <c>XdmNode</c>, the document node at the root of the tree of the resulting
707
        /// in-memory document
708
        /// </returns>
709

  
710
        public XdmNode Build(Stream input)
711
        {
712
            if (baseUri == null)
713
            {
714
                throw new ArgumentException("No base URI supplied");
715
            }
716
            return Build(input, baseUri);
717
        }
718

  
719
        // Build a document from a given stream, with the base URI supplied
720
        // as an extra argument
721

  
722
        internal XdmNode Build(Stream input, Uri baseUri)
723
        {
724
            Source source;
725
            if (processor.GetProperty("http://saxon.sf.net/feature/preferJaxpParser") == "true")
726
            {
727
                source = new StreamSource(new DotNetInputStream(input), baseUri.ToString());
728
                source = AugmentedSource.makeAugmentedSource(source);
729
                ((AugmentedSource)source).setEntityResolver(new DotNetURIResolver(XmlResolver));
730
            }
731
            else
732
            {
733

  
734
                XmlReaderSettings settings = new XmlReaderSettings();
735
                settings.ProhibitDtd = false;   // must expand entity references
736

  
737
                
738
                //((XmlTextReader)parser).Normalization = true;
739
                switch (whitespacePolicy)
740
                {
741
                    case WhitespacePolicy.PreserveAll:
742
                        settings.IgnoreWhitespace = false;
743
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.All;
744
                        break;
745
                    case WhitespacePolicy.StripAll:
746
                        settings.IgnoreWhitespace = true;
747
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.None;
748
                        break;
749
                    case WhitespacePolicy.StripIgnorable:
750
                        settings.IgnoreWhitespace = true;
751
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.Significant;
752
                        break;
753
                }
754
                if (xmlResolver != null)
755
                {
756
                    settings.XmlResolver = xmlResolver;
757
                }
758
                
759
                settings.ValidationType = (dtdValidation ? ValidationType.DTD : ValidationType.None);
760
                
761
                XmlReader parser = XmlReader.Create(input, settings, baseUri.ToString());
762
                source = new PullSource(new DotNetPullProvider(parser));
763
                source.setSystemId(baseUri.ToString());
764
            }
765
            source = augmentSource(source);
766
            DocumentInfo doc = config.buildDocument(source);
767
            return (XdmNode)XdmValue.Wrap(doc);
768
        }
769

  
770
        /// <summary>
771
        /// Load an XML document supplied using a TextReader.
772
        /// </summary>
773
        /// <remarks>
774
        /// <para>The document is parsed using the Microsoft <c>System.Xml</c> parser if the
775
        /// "http://saxon.sf.net/feature/preferJaxpParser" property on the <c>Processor</c> is set to false;
776
        /// otherwise it is parsed using the Apache Xerces XML parser.</para>
777
        /// <para>Before calling this method, the <c>BaseUri</c> property must be set to identify the
778
        /// base URI of this document, used for resolving any relative URIs contained within it.</para>
779
        /// <para>Note that the Microsoft <c>System.Xml</c> parser does not report whether attributes are
780
        /// defined in the DTD as being of type <c>ID</c> and <c>IDREF</c>. This is true whether or not
781
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
782
        /// <c>id()</c> and <c>idref()</c> functions.</para>         
783
        /// </remarks>
784
        /// <param name="input">The <c>TextReader</c> containing the XML source to be parsed</param>
785
        /// <returns>An <c>XdmNode</c>, the document node at the root of the tree of the resulting
786
        /// in-memory document
787
        /// </returns>
788

  
789
        public XdmNode Build(TextReader input)
790
        {
791
            if (baseUri == null)
792
            {
793
                throw new ArgumentException("No base URI supplied");
794
            }
795
            return Build(input, baseUri);
796
        }
797

  
798
        // Build a document from a given stream, with the base URI supplied
799
        // as an extra argument
800

  
801
        internal XdmNode Build(TextReader input, Uri baseUri)
802
        {
803
            Source source;
804
            if (processor.GetProperty("http://saxon.sf.net/feature/preferJaxpParser") == "true")
805
            {
806
                source = new StreamSource(new DotNetReader(input), baseUri.ToString());
807
                source = AugmentedSource.makeAugmentedSource(source);
808
                ((AugmentedSource)source).setEntityResolver(new DotNetURIResolver(XmlResolver));
809
            }
810
            else
811
            {
812

  
813
                XmlReaderSettings settings = new XmlReaderSettings();
814
                settings.ProhibitDtd = false;   // must expand entity references
815

  
816

  
817
                //((XmlTextReader)parser).Normalization = true;
818
                switch (whitespacePolicy)
819
                {
820
                    case WhitespacePolicy.PreserveAll:
821
                        settings.IgnoreWhitespace = false;
822
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.All;
823
                        break;
824
                    case WhitespacePolicy.StripAll:
825
                        settings.IgnoreWhitespace = true;
826
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.None;
827
                        break;
828
                    case WhitespacePolicy.StripIgnorable:
829
                        settings.IgnoreWhitespace = true;
830
                        //((XmlTextReader)parser).WhitespaceHandling = WhitespaceHandling.Significant;
831
                        break;
832
                }
833
                if (xmlResolver != null)
834
                {
835
                    settings.XmlResolver = xmlResolver;
836
                }
837

  
838
                settings.ValidationType = (dtdValidation ? ValidationType.DTD : ValidationType.None);
839

  
840
                XmlReader parser = XmlReader.Create(input, settings, baseUri.ToString());
841
                source = new PullSource(new DotNetPullProvider(parser));
842
                source.setSystemId(baseUri.ToString());
843
            }
844
            source = augmentSource(source);
845
            DocumentInfo doc = config.buildDocument(source);
846
            return (XdmNode)XdmValue.Wrap(doc);
847
        }
848

  
849
        private Source augmentSource(Source source)
850
        {
851
            if (validation != SchemaValidationMode.None)
852
            {
853
                source = AugmentedSource.makeAugmentedSource(source);
854
                if (validation == SchemaValidationMode.Strict)
855
                {
856
                    ((AugmentedSource)source).setSchemaValidationMode(JValidation.STRICT);
857
                }
858
                else if (validation == SchemaValidationMode.Lax)
859
                {
860
                    ((AugmentedSource)source).setSchemaValidationMode(JValidation.LAX);
861
                }
862
                else if (validation == SchemaValidationMode.None)
863
                {
864
                    ((AugmentedSource)source).setSchemaValidationMode(JValidation.STRIP);
865
                }
866
                else if (validation == SchemaValidationMode.Preserve)
867
                {
868
                    ((AugmentedSource)source).setSchemaValidationMode(JValidation.PRESERVE);
869
                }
870
            }
871
            if (topLevelElement != null)
872
            {
873
                source = AugmentedSource.makeAugmentedSource(source);
874
                ((AugmentedSource)source).setTopLevelElement(
875
                    new StructuredQName(
876
                        topLevelElement.Prefix, topLevelElement.Uri, topLevelElement.LocalName));
877
            }
878

  
879
            if (whitespacePolicy != WhitespacePolicy.PreserveAll)
880
            {
881
                source = AugmentedSource.makeAugmentedSource(source);
882
                if (whitespacePolicy == WhitespacePolicy.StripIgnorable)
883
                {
884
                    ((AugmentedSource)source).setStripSpace(Whitespace.IGNORABLE);
885
                }
886
                else
887
                {
888
                    ((AugmentedSource)source).setStripSpace(Whitespace.ALL);
889
                }
890
            }
891
            if (treeModel != TreeModel.Unspecified)
892
            {
893
                source = AugmentedSource.makeAugmentedSource(source);
894
                if (treeModel == TreeModel.TinyTree)
895
                {
896
                    ((AugmentedSource)source).setModel(net.sf.saxon.om.TreeModel.TINY_TREE);
897
                }
898
                else if (treeModel == TreeModel.TinyTreeCondensed)
899
                {
900
                    ((AugmentedSource)source).setModel(net.sf.saxon.om.TreeModel.TINY_TREE_CONDENSED);
901
                }
902
                else
903
                {
904
                    ((AugmentedSource)source).setModel(net.sf.saxon.om.TreeModel.LINKED_TREE);
905
                }
906
            }
907
            if (lineNumbering)
908
            {
909
                source = AugmentedSource.makeAugmentedSource(source);
910
                ((AugmentedSource)source).setLineNumbering(true);
911
            }
912
            if (dtdValidation)
913
            {
914
                source = AugmentedSource.makeAugmentedSource(source);
915
                ((AugmentedSource)source).setDTDValidationMode(JValidation.STRICT);
916
            }
917
            return source;
918
        }
919

  
920
        /// <summary>
921
        /// Load an XML document, delivered using an XmlReader.
922
        /// </summary>
923
        /// <remarks>
924
        /// <para>The XmlReader is responsible for parsing the document; this method builds a tree
925
        /// representation of the document (in an internal Saxon format) and returns its document node.
926
        /// The XmlReader is not required to perform validation but it must expand any entity references.
927
        /// Saxon uses the properties of the <c>XmlReader</c> as supplied.</para>
928
        /// <para>Use of a plain <c>XmlTextReader</c> is discouraged, because it does not expand entity
929
        /// references. This should only be used if you know in advance that the document will contain
930
        /// no entity references (or perhaps if your query or stylesheet is not interested in the content
931
        /// of text and attribute nodes). Instead, with .NET 1.1 use an <c>XmlValidatingReader</c> (with <c>ValidationType</c>
932
        /// set to <c>None</c>). The constructor for <c>XmlValidatingReader</c> is obsolete in .NET 2.0,
933
        /// but the same effect can be achieved by using the <c>Create</c> method of <c>XmlReader</c> with
934
        /// appropriate <c>XmlReaderSettings</c></para>
935
        /// <para>Conformance with the W3C specifications requires that the <c>Normalization</c> property
936
        /// of an <c>XmlTextReader</c> should be set to <c>true</c>. However, Saxon does not insist
937
        /// on this.</para>
938
        /// <para>If the <c>XmlReader</c> performs schema validation, Saxon will ignore any resulting type
939
        /// information. Type information can only be obtained by using Saxon's own schema validator, which
940
        /// will be run if the <c>SchemaValidationMode</c> property is set to <c>Strict</c> or <c>Lax</c></para>
941
        /// <para>Note that the Microsoft <c>System.Xml</c> parser does not report whether attributes are
942
        /// defined in the DTD as being of type <c>ID</c> and <c>IDREF</c>. This is true whether or not
943
        /// DTD-based validation is enabled. This means that such attributes are not accessible to the 
944
        /// <c>id()</c> and <c>idref()</c> functions.</para>
945
        /// <para>Note that setting the <c>XmlResolver</c> property of the <c>DocumentBuilder</c>
946
        /// has no effect when this method is used; if an <c>XmlResolver</c> is required, it must
947
        /// be set on the <c>XmlReader</c> itself.</para>
948
        /// </remarks>
949
        /// <param name="reader">The XMLReader that supplies the parsed XML source</param>
950
        /// <returns>An <c>XdmNode</c>, the document node at the root of the tree of the resulting
951
        /// in-memory document
952
        /// </returns>
953

  
954
        public XdmNode Build(XmlReader reader)
955
        {
956
            PullProvider pp = new DotNetPullProvider(reader);
957
            pp.setPipelineConfiguration(config.makePipelineConfiguration());
958
            // pp = new PullTracer(pp);  /* diagnostics */
959
            Source source = new PullSource(pp);
960
            source.setSystemId(reader.BaseURI);
961
            source = augmentSource(source);
962
            DocumentInfo doc = config.buildDocument(source);
963
            return (XdmNode)XdmValue.Wrap(doc);
964
        }
965

  
966
        /// <summary>
967
        /// Load an XML DOM document, supplied as an <c>XmlNode</c>, into a Saxon XdmNode.
968
        /// </summary>
969
        /// <remarks>
970
        /// <para>
971
        /// The returned document will contain only the subtree rooted at the supplied node.
972
        /// </para>
973
        /// <para>
974
        /// This method copies the DOM tree to create a Saxon tree. See the <c>Wrap</c> method for
975
        /// an alternative that creates a wrapper around the DOM tree, allowing it to be modified in situ.
976
        /// </para>
977
        /// </remarks>
978
        /// <param name="source">The DOM Node to be copied to form a Saxon tree</param>
979
        /// <returns>An <c>XdmNode</c>, the document node at the root of the tree of the resulting
980
        /// in-memory document
981
        /// </returns>
982

  
983
        public XdmNode Build(XmlNode source)
984
        {
985
            return Build(new XmlNodeReader(source));
986
        }
987

  
988
        /// <summary>
989
        /// Wrap an XML DOM document, supplied as an <c>XmlNode</c>, as a Saxon XdmNode.
990
        /// </summary>
991
        /// <remarks>
992
        /// <para>
993
        /// This method must be applied at the level of the Document Node. Unlike the
994
        /// <c>Build</c> method, the original DOM is not copied. This saves memory and
995
        /// time, but it also means that it is not possible to perform operations such as
996
        /// whitespace stripping and schema validation.
997
        /// </para>
998
        /// </remarks>
999
        /// <param name="doc">The DOM document node to be wrapped</param>
1000
        /// <returns>An <c>XdmNode</c>, the Saxon document node at the root of the tree of the resulting
1001
        /// in-memory document
1002
        /// </returns>
1003

  
1004
        public XdmNode Wrap(XmlDocument doc)
1005
        {
1006
            String baseu = (baseUri == null ? null : baseUri.ToString());
1007
            JDocumentWrapper wrapper = new JDocumentWrapper(doc, baseu, config);
1008
            return (XdmNode)XdmValue.Wrap(wrapper);
1009
        }
1010

  
1011

  
1012
    }
1013

  
1014

  
1015
    /// <summary>
1016
    /// Enumeration identifying the various Schema validation modes
1017
    /// </summary>
1018

  
1019
    public enum SchemaValidationMode
1020
    {
1021
        /// <summary>No validation (or strip validation, which removes existing type annotations)</summary> 
1022
        None,
1023
        /// <summary>Strict validation</summary>
1024
        Strict,
1025
        /// <summary>Lax validation</summary>
1026
        Lax,
1027
        /// <summary>Validation mode preserve, which preserves any existing type annotations</summary>
1028
        Preserve,
1029
        /// <summary>Unspecified validation: this means that validation is defined elsewhere, for example in the
1030
        /// Saxon Configuration</summary>
1031
        Unspecified
1032
    }
1033

  
1034
    /// <summary>
1035
    /// Enumeration identifying the various Whitespace stripping policies
1036
    /// </summary>
1037

  
1038
    public enum WhitespacePolicy
1039
    {
1040
        /// <summary>No whitespace is stripped</summary> 
1041
        PreserveAll,
1042
        /// <summary>Whitespace text nodes appearing in element-only content are stripped</summary>
1043
        StripIgnorable,
1044
        /// <summary>All whitespace text nodes are stripped</summary>
1045
        StripAll
1046
    }
1047

  
1048
    /// <summary>
1049
    /// Enumeration identifying the different tree model implementations
1050
    /// </summary>
1051
    /// 
1052
    public enum TreeModel
1053
    {
1054
        /// <summary>
1055
        /// Saxon TinyTree. This is the default model and is suitable for most purposes.
1056
        /// </summary>
1057
        TinyTree,
1058
        /// <summary>
1059
        /// Saxon Condensed TinyTree. This is a variant of the TinyTree that shares storage for 
1060
        /// duplicated text and attribute nodes. It gives a further saving in space occupied, at the cost
1061
        /// of some increase in the time taken for tree construction.
1062
        /// </summary>
1063
        TinyTreeCondensed,
1064
        /// <summary>
1065
        /// Saxon LinkedTree. This tree model is primarily useful when using XQuery Update, since it is the
1066
        /// only standard tree model to support updates.
1067
        /// </summary>
1068
        LinkedTree,
1069
        /// <summary>
1070
        /// Unspecified tree model. This value is used to indicate that there is no preference for any specific
1071
        /// tree model, which allows the choice to fall back to other interfaces.
1072
        /// </summary>
1073
        Unspecified
1074
    }
1075

  
1076
    internal class DotNetObjectModelDefinition : JDotNetObjectModel
1077
    {
1078

  
1079
        public override bool isXdmValue(object obj)
1080
        {
1081
            return obj is XdmValue;
1082
        }
1083

  
1084
        public override bool isXdmAtomicValueType(Type type)
1085
        {
1086
            return typeof(XdmAtomicValue).IsAssignableFrom(type);
1087
        }
1088

  
1089
        public override bool isXdmValueType(Type type)
1090
        {
1091
            return typeof(XdmValue).IsAssignableFrom(type);
1092
        }
1093

  
1094
        public override JValueRepresentation unwrapXdmValue(object obj)
1095
        {
1096
            return ((XdmValue)obj).Unwrap();
1097
        }
1098

  
1099
        public override object wrapAsXdmValue(JValue value)
1100
        {
1101
            return XdmValue.Wrap(value);
1102
        }
1103

  
1104
        public override bool isXmlNodeType(Type type)
1105
        {
1106
            return typeof(System.Xml.XmlNode).IsAssignableFrom(type);
1107
        }
1108

  
1109
    }
1110

  
1111
}
1112

  
1113
//
1114
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
1115
// you may not use this file except in compliance with the License. You may obtain a copy of the
1116
// License at http://www.mozilla.org/MPL/
1117
//
1118
// Software distributed under the License is distributed on an "AS IS" basis,
1119
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
1120
// See the License for the specific language governing rights and limitations under the License.
1121
//
1122
// The Original Code is: all this file.
1123
//
1124
// The Initial Developer of the Original Code is Michael H. Kay.
1125
//
1126
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
1127
//
1128
// Contributor(s): none.
1129
//
tags/9.4.0.7/hen/csource/api/Saxon.Api/Destination.cs
1
´╗┐using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections;
5
using JConfiguration = net.sf.saxon.Configuration;
6
using JPipelineConfiguration = net.sf.saxon.@event.PipelineConfiguration;
7
using JReceiver = net.sf.saxon.@event.Receiver;
8
using JSink = net.sf.saxon.@event.Sink;
9
using JProperties = java.util.Properties;
10
using JOutputStream = java.io.OutputStream;
11
using JWriter = java.io.Writer;
12
using JFileOutputStream = java.io.FileOutputStream;
13
using JXPathException = net.sf.saxon.trans.XPathException;
14
using JResult = javax.xml.transform.Result;
15
using JStreamResult = javax.xml.transform.stream.StreamResult;
16
using JBuilder = net.sf.saxon.@event.Builder;
17
using JTinyBuilder = net.sf.saxon.tree.tiny.TinyBuilder;
18
using JLinkedTreeBuilder = net.sf.saxon.tree.linked.LinkedTreeBuilder;
19
using net.sf.saxon.@event;
20
using net.sf.saxon.lib;
21
using net.sf.saxon.om;
22
using net.sf.saxon.value;
23
using net.sf.saxon.query;
24
using net.sf.saxon.dotnet;
25

  
26

  
27
namespace Saxon.Api
28
{
29

  
30

  
31

  
32
    /// <summary>
33
    /// An abstract destination for the results of a query or transformation
34
    /// </summary>
35
    /// <remarks>
36
    /// <para>Note to implementors: To implement a new kind of destination, you need
37
    /// to supply a method <c>getResult</c> which returns an implementation of
38
    /// the JAXP <c>Result</c> interface. Optionally, if the destination
39
    /// performs serialization, you can also implement <c>getOutputProperties</c>,
40
    /// which returns the properties used for serialization.
41
    /// </para>
42
    /// </remarks>
43

  
44

  
45
    public abstract class XmlDestination
46
    {
47

  
48
        /// <summary>
49
        /// Get a <c>Result</c> to which the XML document can be sent as a series
50
        /// of events. This method is intended primarily for internal use.
51
        /// </summary>
52
        /// <remarks>
53
        /// The returned value must be an implementation of the JAXP <c>Result</c> interface that is
54
        /// recognized by Saxon.
55
        /// </remarks>
56
        /// <param name="pipe">Configuration information for use by the implementation</param>
57

  
58
        public abstract JResult GetResult(JPipelineConfiguration pipe);
59

  
60
        /// <summary>
61
        /// Get a set of <c>Properties</c> representing the parameters to the serializer.
62
        /// The default implementation returns an empty set of properties.
63
        /// </summary>
64

  
65
        public virtual JProperties GetOutputProperties()
66
        {
67
            return new JProperties();
68
        }
69

  
70
        /// <summary>
71
        /// Close the Destination, releasing any resources that need to be released.
72
        /// </summary>
73
        /// <remarks>
74
        /// This method is called by the system on completion of a query or transformation.
75
        /// Some kinds of Destination may need to close an output stream, others might
76
        /// not need to do anything. The default implementation does nothing.
77
        /// </remarks>
78

  
79
        public virtual void Close()
80
        {
81
        }
82

  
83

  
84
    }
85

  
86
    /// <summary>
87
    /// A <c>Serializer</c> takes a tree representation of XML and turns
88
    /// it into lexical XML markup.
89
    /// </summary>
90
    /// <remarks>
91
    /// Note that this is serialization in the sense of the W3C XSLT and XQuery specifications.
92
    /// Unlike the class <c>System.Xml.Serialization.XmlSerializer</c>, this object does not
93
    /// serialize arbitrary CLI objects.
94
    /// </remarks>
95

  
96
    public class Serializer : XmlDestination
97
    {
98

  
99
        private JProperties props = new JProperties();
100
        private JOutputStream outputStream = null;
101
        private JWriter writer = null;
102
        private bool mustClose = true;
103

  
104

  
105
        /// <summary>QName identifying the serialization parameter "method". If the method
106
        /// is a user-defined method, then it is given as a QName in Clark notation, that is
107
        /// "{uri}local".</summary>
108

  
109
        public static readonly QName METHOD =
110
            new QName("", "method");
111

  
112
        /// <summary>QName identifying the serialization parameter "byte-order-mark"</summary>
113

  
114
        public static readonly QName BYTE_ORDER_MARK =
115
            new QName("", "byte-order-mark");
116

  
117
        /// <summary>QName identifying the serialization parameter "cdata-section-elements".
118
        /// The value of this parameter is given as a space-separated list of expanded QNames in
119
        /// Clark notation, that is "{uri}local".</summary>
120

  
121
        public static readonly QName CDATA_SECTION_ELEMENTS =
122
            new QName("", "cdata-section-elements");
123

  
124
        /// <summary>QName identifying the serialization parameter "doctype-public"</summary>
125

  
126
        public static readonly QName DOCTYPE_PUBLIC =
127
            new QName("", "doctype-public");
128

  
129
        /// <summary>QName identifying the serialization parameter "doctype-system"</summary>
130

  
131
        public static readonly QName DOCTYPE_SYSTEM =
132
            new QName("", "doctype-system");
133

  
134
        /// <summary>QName identifying the serialization parameter "encoding"</summary>
135

  
136
        public static readonly QName ENCODING =
137
            new QName("", "encoding");
138

  
139
        /// <summary>QName identifying the serialization parameter "escape-uri-attributes".
140
        /// The value is the string "yes" or "no".</summary>
141

  
142
        public static readonly QName ESCAPE_URI_ATTRIBUTES =
143
            new QName("", "escape-uri-attributes");
144

  
145
        /// <summary>QName identifying the serialization parameter "include-content-type".
146
        /// The value is the string "yes" or "no".</summary>
147

  
148
        public static readonly QName INCLUDE_CONTENT_TYPE =
149
            new QName("", "include-content-type");
150

  
151
        /// <summary>QName identifying the serialization parameter "indent".
152
        /// The value is the string "yes" or "no".</summary>
153

  
154
        public static readonly QName INDENT =
155
            new QName("", "indent");
156

  
157
        /// <summary>QName identifying the serialization parameter "media-type".</summary>
158

  
159
        public static readonly QName MEDIA_TYPE =
160
            new QName("", "media-type");
161

  
162
        /// <summary>QName identifying the serialization parameter "normalization-form"</summary>
163

  
164
        public static readonly QName NORMALIZATION_FORM =
165
            new QName("", "normalization-form");
166

  
167
        /// <summary>QName identifying the serialization parameter "omit-xml-declaration".
168
        /// The value is the string "yes" or "no".</summary>
169

  
170
        public static readonly QName OMIT_XML_DECLARATION =
171
            new QName("", "omit-xml-declaration");
172

  
173
        /// <summary>QName identifying the serialization parameter "standalone".
174
        /// The value is the string "yes" or "no" or "omit".</summary>
175

  
176
        public static readonly QName STANDALONE =
177
            new QName("", "standalone");
178

  
179
        /// <summary>QName identifying the serialization parameter "suppress-indentation"
180
        /// (introduced in XSLT/XQuery 3.0). Previously available as "saxon:suppress-indentation"
181
        /// The value is the string "yes" or "no" or "omit".</summary>
182

  
183
        public static readonly QName SUPPRESS_INDENTATION =
184
            new QName("", "suppress-indentation");
185

  
186
        /// <summary>QName identifying the serialization parameter "undeclare-prefixes".
187
        /// The value is the string "yes" or "no".</summary>
188

  
189
        public static readonly QName UNDECLARE_PREFIXES =
190
            new QName("", "undeclare-prefixes");
191

  
192
        /// <summary>QName identifying the serialization parameter "use-character-maps".
193
        /// This is available only with XSLT. The value of the parameter is a list of expanded QNames
194
        /// in Clark notation giving the names of character maps defined in the XSLT stylesheet.</summary>
195

  
196
        public static readonly QName USE_CHARACTER_MAPS =
197
            new QName("", "use-character-maps");
198

  
199
        /// <summary>QName identifying the serialization parameter "version"</summary>
200

  
201
        public static readonly QName VERSION =
202
            new QName("", "version");
203

  
204
        private const String SAXON = NamespaceConstant.SAXON;
205

  
206

  
207
        /// <summary>QName identifying the serialization parameter "saxon:character-representation"</summary>
208

  
209

  
210
        public static readonly QName SAXON_CHARACTER_REPRESENTATION =
211
            new QName(SAXON, "saxon:character-representation");
212

  
213
        /// <summary>QName identifying the serialization parameter "saxon:indent-spaces". The value
214
        /// is an integer (represented as a string) indicating the amount of indentation required.
215
        /// If specified, this parameter overrides indent="no".</summary>
216

  
217
        public static readonly QName SAXON_INDENT_SPACES =
218
            new QName(SAXON, "saxon:indent-spaces");
219

  
220
        /// <summary>QName identifying the serialization parameter "saxon:double-space". The value of this 
221
        /// parameter is given as a space-separated list of expanded QNames in Clark notation, that is 
222
        /// "{uri}local"; each QName identifies an element that should be preceded by an extra blank line within
223
        /// indented output.</summary>
224

  
225
        public static readonly QName SAXON_DOUBLE_SPACE =
226
            new QName(SAXON, "saxon:double-space");
227

  
228
        /// <summary>QName identifying the serialization parameter "saxon:double-space". The value of this 
229
        /// parameter is given as a space-separated list of expanded QNames in Clark notation, that is 
230
        /// "{uri}local"; each QName identifies an element whose content should not be indented even when
231
        /// indent=yes is specified.</summary>
232

  
233
        public static readonly QName SAXON_SUPPRESS_INDENTATION =
234
            new QName(SAXON, "saxon:suppress-indentation");
235

  
236
        /// <summary>QName identifying the serialization parameter "saxon:next-in-chain". This
237
        /// is available only with XSLT, and identifies the URI of a stylesheet that is to be used to
238
        /// process the results before passing them to their final destination.</summary>
239

  
240
        public static readonly QName NEXT_IN_CHAIN =
241
            new QName(SAXON, "saxon:next-in-chain");
242

  
243
        /// <summary>QName identifying the serialization parameter "saxon:require-well-formed". The
244
        /// value is the string "yes" or "no". If set to "yes", the output must be a well-formed
245
        /// document, or an error will be reported. ("Well-formed" here means that the document node
246
        /// must have exactly one element child, and no text node children other than whitespace-only
247
        /// text nodes).</summary>
248

  
249
        public static readonly QName SAXON_REQUIRE_WELL_FORMED =
250
            new QName(SAXON, "saxon:require-well-formed");
251

  
252

  
253
        /// <summary>Create a Serializer</summary>
254

  
255
        public Serializer()
256
        {
257
        }
258

  
259
        /// <summary>Set a serialization property</summary>
260
        /// <remarks>In the case of XSLT, properties set within the serializer override
261
        /// any properties set in <c>xsl:output</c> declarations in the stylesheet.
262
        /// Similarly, with XQuery, they override any properties set in the Query
263
        /// prolog using <c>declare option saxon:output</c>.</remarks>
264
        /// <example>
265
        ///   <code>
266
        ///     Serializer qout = new Serializer();
267
        ///     qout.SetOutputProperty(Serializer.METHOD, "xml");
268
        ///     qout.SetOutputProperty(Serializer.INDENT, "yes");
269
        ///     qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1");
270
        ///   </code>
271
        /// </example> 
272
        /// <param name="name">The name of the serialization property to be set</param>
273
        /// <param name="value">The value to be set for the serialization property. May be null
274
        /// to unset the property (that is, to set it back to the default value).</param>
275

  
276
        public void SetOutputProperty(QName name, String value)
277
        {
278
            props.setProperty(name.ClarkName, value);
279
        }
280

  
281
        /// <summary>Specify the destination of the serialized output, in the
282
        /// form of a file name</summary>
283
        /// <param name="filename">The name of the file to receive the serialized output</param>
284
        /// <exception>Throws a <c>DynamicError</c> if it is not possible to create an output
285
        /// stream to write to this file, for example, if the filename is in a directory
286
        /// that does not exist.</exception>
287

  
288
        public void SetOutputFile(String filename)
289
        {
290
            try
291
            {
292
                outputStream = new JFileOutputStream(filename);
293
                mustClose = true;
294
            }
295
            catch (java.io.IOException err)
296
            {
297
                JXPathException e = new JXPathException(err);
298
                throw new DynamicError(e);
299
            }
300
        }
301

  
302
        /// <summary>Specify the destination of the serialized output, in the
303
        /// form of a <c>Stream</c></summary>
304
        /// <remarks>Saxon will not close the stream on completion; this is the
305
        /// caller's responsibility.</remarks>
306
        /// <param name="stream">The stream to which the output will be written.
307
        /// This must be a stream that allows writing.</param>
308

  
309
        public void SetOutputStream(Stream stream)
310
        {
311
            outputStream = new DotNetOutputStream(stream);
312
            mustClose = false;
313
        }
314

  
315
        /// <summary>Specify the destination of the serialized output, in the
316
        /// form of a <c>TextWriter</c></summary>
317
        /// <remarks>Note that when writing to a <c>TextWriter</c>, character encoding is
318
        /// the responsibility of the <c>TextWriter</c>, not the <c>Serializer</c>. This
319
        /// means that the encoding requested in the output properties is ignored; it also
320
        /// means that characters that cannot be represented in the target encoding will
321
        /// use whatever fallback representation the <c>TextWriter</c> defines, rather than
322
        /// being represented as XML character references.</remarks>
323
        /// <param name="textWriter">The stream to which the output will be written.
324
        /// This must be a stream that allows writing. Saxon will not close the
325
        /// <c>textWriter</c> on completion; this is the caller's responsibility.</param>
326

  
327
        public void SetOutputWriter(TextWriter textWriter)
328
        {
329
            writer = new DotNetWriter(textWriter);
330
            mustClose = false;
331
        }
332

  
333
        internal JReceiver GetReceiver(JConfiguration config)
334
        {
335
            JPipelineConfiguration pipe = config.makePipelineConfiguration();
336
            return config.getSerializerFactory().getReceiver(
337
                    GetResult(pipe),
338
                    pipe,
339
                    GetOutputProperties());
340

  
341
        }
342

  
343

  
344
        /// <summary inherit="yes"/>
345

  
346
        public override JResult GetResult(JPipelineConfiguration pipe)
347
        {
348
            if (outputStream != null)
349
            {
350
                return new JStreamResult(outputStream);
351
            }
352
            else if (writer != null)
353
            {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff