Project

Profile

Help

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

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

1
using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections;
5
using System.Collections.Generic;
6
using System.Globalization;
7
using JStreamSource = javax.xml.transform.stream.StreamSource;
8
using JResult = javax.xml.transform.Result;
9
using JTransformerException = javax.xml.transform.TransformerException;
10
using JOutputURIResolver = net.sf.saxon.lib.OutputURIResolver;
11
using JConfiguration = net.sf.saxon.Configuration;
12
using JPipelineConfiguration = net.sf.saxon.@event.PipelineConfiguration;
13
using JSequenceWriter = net.sf.saxon.@event.SequenceWriter;
14
using JReceiver = net.sf.saxon.@event.Receiver;
15
using JReceiverOptions = net.sf.saxon.@event.ReceiverOptions;
16
using JCompilerInfo = net.sf.saxon.trans.CompilerInfo;
17
using JExpressionPresenter = net.sf.saxon.trace.ExpressionPresenter;
18
using JValidation = net.sf.saxon.lib.Validation;
19
using JValidationMode = net.sf.saxon.s9api.ValidationMode;
20
using JCompilation = net.sf.saxon.style.Compilation;
21
using JController = net.sf.saxon.Controller;
22
using JXsltController = net.sf.saxon.trans.XsltController;
23
using JItem = net.sf.saxon.om.Item;
24
using JNodeInfo = net.sf.saxon.om.NodeInfo;
25
using JNodeName = net.sf.saxon.om.NodeName;
26
using JSchemaType = net.sf.saxon.type.SchemaType;
27
using JTreeInfo = net.sf.saxon.om.TreeInfo;
28
using JPullSource = net.sf.saxon.pull.PullSource;
29
using JProcInstParser = net.sf.saxon.tree.util.ProcInstParser;
30
using JXsltCompiler = net.sf.saxon.s9api.XsltCompiler;
31
using JXsltExecutable = net.sf.saxon.s9api.XsltExecutable;
32
using JSaxonApiException = net.sf.saxon.s9api.SaxonApiException;
33
using JDotNetComparator = net.sf.saxon.dotnet.DotNetComparator;
34
using JDotNetURIResolver = net.sf.saxon.dotnet.DotNetURIResolver;
35
using JDotNetInputStream = net.sf.saxon.dotnet.DotNetInputStream;
36
using JDotNetReader = net.sf.saxon.dotnet.DotNetReader;
37
using JDotNetPullProvider = net.sf.saxon.dotnet.DotNetPullProvider;
38
using CharSequence = java.lang.CharSequence;
39
using JXsltTransformer = net.sf.saxon.s9api.XsltTransformer;
40
using JXslt30Transformer = net.sf.saxon.s9api.Xslt30Transformer;
41
using JStylesheetPackage = net.sf.saxon.style.StylesheetPackage;
42
using JXsltPackage = net.sf.saxon.s9api.XsltPackage;
43
using JPackageDetails = net.sf.saxon.trans.packages.PackageDetails;
44
using JPackageLibrary = net.sf.saxon.trans.packages.PackageLibrary;
45
using JVersionedPackageName = net.sf.saxon.trans.packages.VersionedPackageName;
46
using JMap = java.util.Map;
47
using JLocation = net.sf.saxon.expr.parser.Location;
48
using JExplicitLocation = net.sf.saxon.expr.parser.ExplicitLocation;
49
using JDotNetOutputStream = net.sf.saxon.dotnet.DotNetOutputStream;
50
using JDestination = net.sf.saxon.s9api.Destination;
51
using javax.xml.transform;
52
using JResultDocumentResolver = net.sf.saxon.lib.ResultDocumentResolver;
53

    
54
namespace Saxon.Api
55
{
56

    
57
    /// <summary>
58
    /// An <c>XsltCompiler</c> object allows XSLT 3.0 stylesheets to be compiled.
59
    /// The compiler holds information that represents the static context
60
    /// for the compilation.
61
    /// </summary>
62
    /// <remarks>
63
    /// <para>To construct an <c>XsltCompiler</c>, use the factory method
64
	/// <c>NewXsltCompiler</c> on the <see cref="Processor"/> object.</para>
65
    /// <para>An <c>XsltCompiler</c> may be used repeatedly to compile multiple
66
    /// queries. Any changes made to the <c>XsltCompiler</c> (that is, to the
67
    /// static context) do not affect queries that have already been compiled.
68
    /// An <c>XsltCompiler</c> may be used concurrently in multiple threads, but
69
    /// it should not then be modified once initialized.</para>
70
    /// </remarks>
71

    
72
    [Serializable]
73
    public class XsltCompiler
74
    {
75
        private Processor processor;
76
        private Uri baseUri;
77
        private ErrorGatherer errorGatherer;
78
        private IDictionary<QName, XdmValue> variableList = new Dictionary<QName, XdmValue>();
79
        private JXsltCompiler xsltCompiler;
80
        private XmlResolver xmlResolver = null;
81

    
82
        // internal constructor: the public interface is a factory method
83
        // on the Processor object
84

    
85
        internal XsltCompiler(Processor processor)
86
        {
87
            this.processor = processor;
88
            xsltCompiler = processor.JProcessor.newXsltCompiler();
89
            errorGatherer = new ErrorGatherer(new List<StaticError>());
90
            xsltCompiler.setErrorListener(errorGatherer);
91
            xsltCompiler.setURIResolver(processor.Implementation.getURIResolver());
92
        }
93

    
94
        /// <summary>
95
        /// The base URI of the stylesheet, which forms part of the static context
96
        /// of the stylesheet. This is used for resolving any relative URIs appearing
97
        /// within the stylesheet, for example in <c>xsl:include</c> and <c>xsl:import</c>
98
        /// declarations, in schema locations defined to <c>xsl:import-schema</c>, 
99
        /// or as an argument to the <c>document()</c> or <c>doc()</c> function.
100
        /// </summary>
101
        /// <remarks>
102
        /// This base URI is used only if the input supplied to the <c>Compile</c> method
103
        /// does not provide its own base URI. It is therefore used on the version of the
104
        /// method that supplies input from a <c>Stream</c>. On the version that supplies
105
        /// input from an <c>XmlReader</c>, this base URI is used only if the <c>XmlReader</c>
106
        /// does not have its own base URI.
107
        /// </remarks>
108

    
109

    
110
        public Uri BaseUri
111
        {
112
            get { return baseUri; }
113
            set { baseUri = value; }
114
        }
115

    
116
        /// <summary>
117
        /// Create a collation based on a given <c>CompareInfo</c> and <c>CompareOptions</c>.    
118
        /// </summary>
119
        /// <remarks>
120
        /// In the current and recent releases of Saxon, collations are always defined at the level of a <c>Configuration</c>.
121
        /// Declaring a collation here may therefore have wider effects than intended. It is recommended not to use
122
        /// this method, but to use <see cref="Processor.DeclareCollation(Uri, CompareInfo, CompareOptions)"/> instead.
123
        /// </remarks>
124
        /// <param name="uri">The collation URI to be used within the XPath expression to refer to this collation</param>
125
        /// <param name="compareInfo">The <c>CompareInfo</c>, which determines the language-specific
126
        /// collation rules to be used</param>
127
        /// <param name="options">Options to be used in performing comparisons, for example
128
        /// whether they are to be case-blind and/or accent-blind</param>
129
        /// <param name="isDefault">If true, this collation will be used as the default collation</param>
130

    
131
        [Obsolete("Declare collations globally at the Processor level.")]
132
        public void DeclareCollation(Uri uri, CompareInfo compareInfo, CompareOptions options, Boolean isDefault)
133
        {
134
            JDotNetComparator comparator = new JDotNetComparator(uri.ToString(), compareInfo, options);
135
            processor.JProcessor.getUnderlyingConfiguration().registerCollation(uri.ToString(), comparator);
136
        }
137

    
138
        /// <summary>
139
        /// The name of the default collation used by stylesheets compiled using this <c>XsltCompiler</c>.
140
        /// This must be the name of a collation that is known to the <c>Processor</c>.
141
        /// </summary>
142
        
143
		public String DefaultCollationName
144
        {
145
            get { return xsltCompiler.getDefaultCollation(); }
146
            set { xsltCompiler.declareDefaultCollation(value); }
147
        }
148

    
149
        /// <summary>
150
        /// The <c>Processor</c> from which this <c>XsltCompiler</c> was constructed
151
        /// </summary>
152
        
153
		public Processor Processor
154
        {
155
            get { return processor; }
156
        }
157

    
158
        /// <summary>
159
        /// An <c>XmlResolver</c>, which will be used to resolve URI references while compiling
160
        /// a stylesheet.
161
        /// </summary>
162
        /// <remarks>
163
        /// If no <c>XmlResolver</c> is set for the <c>XsltCompiler</c>, the <c>XmlResolver</c>
164
        /// that is used is the one that was set on the <c>Processor</c> at the time <c>NewXsltCompiler</c>
165
        /// was called.
166
        /// </remarks>
167

    
168
        public XmlResolver XmlResolver
169
        {
170
            get
171
            {
172
                if (xmlResolver == null)
173
                {
174
                    javax.xml.transform.URIResolver resolver = xsltCompiler.getUnderlyingCompilerInfo().getURIResolver();
175
                    if (resolver is JDotNetURIResolver)
176
                    {
177
                        return ((JDotNetURIResolver)resolver).getXmlResolver();
178
                    }
179
                    else
180
                    {
181
                        xmlResolver = new XmlUrlResolver();
182
                        return xmlResolver;
183
                    }
184
                }
185
                else
186
                {
187
                    return xmlResolver;
188
                }
189

    
190
            }
191
            set
192
            {
193
                xmlResolver = value;
194
                xsltCompiler.getUnderlyingCompilerInfo().setURIResolver(new JDotNetURIResolver(xmlResolver));
195
            }
196
        }
197

    
198
        /// <summary>
199
        /// The <c>SchemaAware</c> property determines whether the stylesheet is schema-aware. By default, a stylesheet
200
        /// is schema-aware if it contains one or more <code>xsl:import-schema</code> declarations. This option allows
201
        /// a stylesheet to be marked as schema-aware even if it does not contain such a declaration.
202
        /// </summary>
203
        /// <remarks>
204
        /// <para>If the stylesheet is not schema-aware, then schema-validated input documents will be rejected.</para>
205
        /// <para>The reason for this option is that it is expensive to generate code that can handle typed input
206
        /// documents when they will never arise in practice.</para>
207
        /// <para>The initial setting of this property is false, regardless of whether or not the <c>Processor</c>
208
        /// is schema-aware. Setting this property to true if the processor is not schema-aware will cause an Exception.</para>
209
        /// </remarks>
210

    
211
        public bool SchemaAware
212
        {
213
            get
214
            {
215
                return xsltCompiler.isSchemaAware();
216
            }
217
            set
218
            {
219
                xsltCompiler.setSchemaAware(value);
220
            }
221
        }
222

    
223

    
224
        /// <summary>
225
        /// Indicates whether or not assertions (<c>xsl:assert</c> instructions) are enabled at compile time. 
226
        /// </summary>
227
        /// <remarks>By default assertions are disabled at compile time. If assertions are enabled at compile time, then by
228
        /// default they will also be enabled at run time; but they can be disabled at run time by
229
        /// specific request. At compile time, assertions can be enabled for some packages and
230
        /// disabled for others; at run time, they can only be enabled or disabled globally.</remarks>
231
		/// <returns>true if assertions are enabled at compile time</returns>
232

    
233

    
234
        public bool AssertionsEnabled
235
        {
236
            get
237
            {
238
                return xsltCompiler.isAssertionsEnabled();
239
            }
240
            set
241
            {
242
                xsltCompiler.setAssertionsEnabled(value);
243
            }
244
        }
245

    
246
        /// <summary>
247
        /// The <c>XsltLanguageVersion</c> property determines the version of the XSLT language specification
248
        /// implemented by the compiler. In this Saxon release the value is always "3.0".
249
        /// </summary>
250
        /// <remarks>
251
        /// <para>Getting this property always returns "3.0".</para>
252
        /// <para>Setting this property has no effect.</para>
253
        /// </remarks>
254

    
255
        public string XsltLanguageVersion
256
        {
257
            get
258
            {
259
                return "3.0";
260
            }
261
            set
262
            {}
263
        }
264

    
265
        /// <summary>
266
        /// This property determines whether bytecode is to be generated in the compiled stylesheet.
267
        /// </summary>
268
        /// <remarks>
269
        /// <para>
270
        /// Bytecode generation is enabled by default in Saxon-EE, but can be disabled by clearing this property.
271
        /// In Saxon-HE and Saxon-PE, attempting to set this property to true either has no effect, or causes an error.
272
        /// </para>
273
        /// <para>
274
        /// Setting this property on causes bytecode to be generated for sections of the stylesheet that are
275
        /// executed frequently enough to justify it. It does not force immediate (eager) byte code generation.
276
        /// </para>
277
        /// </remarks>
278
		/// <returns>true if bytecode is to be generated, false if not</returns>
279
        
280
		public bool ByteCodeEnabled {
281
            
282
            get{ return xsltCompiler.getUnderlyingCompilerInfo().isGenerateByteCode(); }
283
            set { xsltCompiler.getUnderlyingCompilerInfo().setGenerateByteCode(value); }
284
        }
285

    
286

    
287

    
288
        /// <summary>
289
        /// List of errors. The caller should supply an empty list before calling Compile;
290
        /// the processor will then populate the list with error information obtained during
291
        /// the compilation. Each error will be included as an object of type <c>StaticError</c>.
292
        /// If no error list is supplied by the caller, error information will be written to
293
        /// an error list allocated by the system, which can be obtained as the value of this property.
294
        /// </summary>
295
        /// <remarks>
296
		/// By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
297
        /// intercept error conditions as they occur.
298
        /// </remarks>
299

    
300
        public IList<StaticError> ErrorList
301
        {
302
            set
303
            {
304
                errorGatherer = new ErrorGatherer(value);
305
                xsltCompiler.setErrorListener(errorGatherer);
306
            }
307
            get
308
            {
309
                return errorGatherer.ErrorList;
310
            }
311
        }
312

    
313
        /// <summary>
314
        /// Compile a stylesheet supplied as a Stream.
315
        /// </summary>
316
        /// <example>
317
        /// <code>
318
        /// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
319
        /// XsltExecutable q = compiler.Compile(source);
320
        /// source.Close();
321
        /// </code>
322
        /// </example>
323
        /// <param name="input">A stream containing the source text of the stylesheet</param>
324
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
325
		/// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
326
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
327
        /// once it has been compiled.</returns>
328
        /// <remarks>
329
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
330
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
331
        /// <para>The stylesheet is contained in the part of the input stream between its current
332
        /// position and the end of the stream. It is the caller's responsibility to close the input 
333
        /// stream after use. If the compilation succeeded, then on exit the stream will be 
334
        /// exhausted; if compilation failed, the current position of the stream on exit is
335
        /// undefined.</para>
336
        /// </remarks>
337

    
338
        public XsltExecutable Compile(Stream input)
339
        {
340
            try
341
            {
342
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
343
                if (baseUri != null)
344
                {
345
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
346
                }
347
                
348
                return new XsltExecutable(xsltCompiler.compile(ss));
349
            }
350
            catch (JSaxonApiException err)
351
            {
352
                throw new StaticError(err);
353
            }
354
        }
355

    
356
		// internal method: Compile a stylesheet supplied as a Stream.
357
		// For example:
358
		// <code>
359
		// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
360
		// XsltExecutable q = compiler.Compile(source);
361
		// source.Close();
362
		// </code>
363
		// <param name="input">A stream containing the source text of the stylesheet</param>
364
		// <param name="theBaseUri">Specify the base URI of the stream</param>
365
		// <param name="closeStream">Flag to indicate if the stream should be closed in the method</param>
366
		// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
367
		// The XsltExecutable may be loaded as many times as required, in the same or a different
368
		// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
369
		// once it has been compiled.</returns>
370
		// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
371
		// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
372
		// <para>The stylesheet is contained in the part of the input stream between its current
373
		// position and the end of the stream. It is the caller's responsibility to close the input 
374
		// stream after use. If the compilation succeeded, then on exit the stream will be 
375
		// exhausted; if compilation failed, the current position of the stream on exit is
376
		// undefined.</para>
377

    
378
        internal XsltExecutable Compile(Stream input, String theBaseUri, bool closeStream)
379
        {
380
            //See bug 2306
381
            try
382
            {
383
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
384
                if (theBaseUri != null)
385
                {
386
                    ss.setSystemId(Uri.EscapeUriString(theBaseUri.ToString()));
387
                }
388
                else
389
                {
390
                    if (baseUri != null)
391
                    {
392
                        ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
393
                    }
394
                }
395
                JXsltExecutable executable =  xsltCompiler.compile(ss);
396
               
397
                if (closeStream)
398
                {
399
                    input.Close();
400
                }
401
                return new XsltExecutable(executable);
402
            }
403
            catch (JSaxonApiException err)
404
            {
405
                throw new StaticError(err);
406
            }
407
        }
408

    
409

    
410

    
411
		/// <summary>Compile a library package.</summary>
412
		/// <remarks>
413
        /// <para>The source argument identifies an XML file containing an <c>xsl:package</c> element. Any packages
414
        /// on which this package depends must have been made available to the <c>XsltCompiler</c>
415
        /// by importing them using <see cref="ImportPackage"/>.</para>
416
		/// </remarks>
417
        /// <param name='input'>source identifies an XML document holding the the XSLT package to be compiled</param>
418
        /// <returns>The <c>XsltPackage</c> that results from the compilation. Note that this package
419
        /// is not automatically imported to this <c>XsltCompiler</c>; if the package is required
420
        /// for use in subsequent compilations then it must be explicitly imported.</returns>
421

    
422
        public XsltPackage CompilePackage(Stream input)
423
        {
424
            try
425
            {
426
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
427
                if (baseUri != null)
428
                {
429
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
430
                }
431

    
432
                return new XsltPackage(processor, xsltCompiler.compilePackage(ss));
433
            }
434
            catch (JSaxonApiException err)
435
            {
436
                throw new StaticError(err);
437
            }
438
        }
439

    
440

    
441

    
442

    
443
        /// <summary>Compile a list of packages.</summary>
444
        /// <param name='sources'> the collection of packages to be compiled, in the form of an
445
		/// <c>Iterable</c></param>
446
		/// <returns> the collection of compiled packages, in the form of an <c>Iterable</c></returns> 
447
        [Obsolete("CompilePackages is deprecated, please use configuration to add list of packages.")]
448
        public IList<XsltPackage> CompilePackages(IList<String> sources)
449
        {
450
            JCompilerInfo compilerInfo = xsltCompiler.getUnderlyingCompilerInfo();
451
            JConfiguration config = xsltCompiler.getUnderlyingCompilerInfo().getConfiguration();
452
            JCompilation compilation = new JCompilation(config,compilerInfo);
453
            
454
             java.util.Set sourcesJList = new java.util.HashSet();
455

    
456
            foreach (String sourceStr in sources)
457
            {
458
                sourcesJList.add(new java.io.File(sourceStr));
459

    
460
            }
461

    
462

    
463
            java.lang.Iterable resultJList = null;
464

    
465
            try
466
            {
467
                compilerInfo.setPackageLibrary(new JPackageLibrary(compilerInfo, sourcesJList));
468

    
469
                resultJList =compilerInfo.getPackageLibrary().getPackages();
470

    
471

    
472
            }
473
            catch (JTransformerException ex)
474
            {
475
                throw new StaticError(ex);
476
            }
477
            IList<XsltPackage> result = new List<XsltPackage>();
478
            java.util.Iterator iter = resultJList.iterator();
479

    
480
            for (; iter.hasNext();)
481
            {
482
                JXsltPackage pp = (JXsltPackage)iter.next();
483
                result.Add(new XsltPackage(processor, pp));
484
            }
485

    
486
            return result;
487
        }
488

    
489

    
490

    
491

    
492
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
493
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
494
        /// <code>XsltCompiler</code>.</summary>
495
        /// <param name='thePackage'> the package to be imported</param>
496
        /// <remarks>since 9.6</remarks>
497

    
498
        public void ImportPackage(XsltPackage thePackage)
499
        {
500
            if (thePackage.Processor != this.processor)
501
            {
502
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
503
            }
504
            GetUnderlyingCompilerInfo().getPackageLibrary().addPackage(thePackage.getUnderlyingPreparedPackage());
505
        }
506

    
507

    
508
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
509
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
510
        /// <code>XsltCompiler</code>.</summary>
511
		/// <param name='thePackage'> the package to be imported</param>
512
		/// <param name='packageName'> name of the package to be imported</param>
513
		/// <param name='version'> version identifier for the package to be imported</param>
514
        /// <remarks>since 9.8</remarks>
515

    
516
        public void ImportPackage(XsltPackage thePackage, string packageName, string version)
517
        {
518
            if (thePackage.Processor != this.processor)
519
            {
520
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
521
            }
522
            try {
523
                JPackageDetails details = new JPackageDetails();
524
                if (packageName == null) {
525
                    packageName = thePackage.PackageName;
526
                }
527
                if (version == null) {
528
                    version = thePackage.Version;
529
                }
530
                details.nameAndVersion = new JVersionedPackageName(packageName, version);
531
                details.loadedPackage = thePackage.getUnderlyingPreparedPackage();
532
                xsltCompiler.getUnderlyingCompilerInfo().getPackageLibrary().addPackage(details);
533
            } catch (JTransformerException ex) {
534
                throw new StaticError(ex);
535
            }
536
        }
537

    
538

    
539
        /// <summary>
540
		/// Load a compiled package from a file or from a remote location.
541
		/// </summary>
542
		/// <remarks>
543
        /// The supplied URI represents the location of a resource which must have been originally
544
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
545
        /// The result of loading the package is returned as an <code>XsltPackage</code> object.
546
        /// Note that this package is not automatically imported to this <code>XsltCompiler</code>;
547
        /// if the package is required for use in subsequent compilations then it must be explicitly
548
        /// imported.
549
		/// </remarks>
550
        /// <param name="location">the location from which the package is to be loaded, as a URI</param>
551
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
552

    
553
        public XsltPackage LoadLibraryPackage(Uri location)
554
        {
555
            try
556
            {
557
                JXsltPackage package = xsltCompiler.loadLibraryPackage(new java.net.URI(location.ToString()));
558
                return new XsltPackage(processor, package);
559

    
560
            }
561
            catch (net.sf.saxon.trans.XPathException e)
562
            {
563
                throw new StaticError(e);
564
            }
565

    
566

    
567
        }
568

    
569
        /// <summary>
570
        /// Load a compiled package from a file or from a remote location, with the intent to use this as a complete
571
		/// executable stylesheet, not as a library package.
572
		/// </summary>
573
		/// <remarks>
574
        /// The supplied URI represents the location of a resource which must have been originally
575
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
576
		/// </remarks>
577
        /// <param name="location"> the location from which the package is to be loaded, as a URI</param>
578
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
579

    
580
        public XsltExecutable LoadExecutablePackage(Uri location)
581
        {
582
            return LoadLibraryPackage(location).Link();
583

    
584
        }
585

    
586

    
587
        ///	<summary>  
588
		/// Get the underlying <c>CompilerInfo</c> object, which provides more detailed (but less stable) control
589
        /// over some compilation options
590
        /// </summary>
591
		/// <returns> the underlying <c>CompilerInfo</c> object, which holds compilation-time options. The methods on
592
        /// this object are not guaranteed stable from release to release.
593
        /// </returns>
594

    
595
        public JCompilerInfo GetUnderlyingCompilerInfo()
596
        {
597
            return xsltCompiler.getUnderlyingCompilerInfo();
598
        }
599

    
600

    
601
        /// <summary>
602
        /// Externally set the value of a static parameter (new facility in XSLT 3.0) 
603
        /// </summary>
604
        /// <param name="name">The name of the parameter, expressed
605
        /// as a QName. If a parameter of this name has been declared in the
606
        /// stylesheet, the given value will be assigned to the variable. If the
607
        /// variable has not been declared, calling this method has no effect (it is
608
        /// not an error).</param>
609
        /// <param name="value">The value to be given to the parameter.
610
        /// If the parameter declaration defines a required type for the variable, then
611
        /// this value will be converted in the same way as arguments to function calls
612
        /// (for example, numeric promotion is applied).</param>
613

    
614
        public void SetParameter(QName name, XdmValue value)
615
        {
616
            if (value == null)
617
            {
618
                if (variableList.ContainsKey(name))
619
                {
620
                    variableList.Remove(name);
621
                    xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), null);
622
                }
623
            }
624
            else
625
            {
626
                variableList[name] = value;
627
                xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), value.value);
628
            }
629
        }
630

    
631
        /// <summary>
632
        /// Property to check and set fast compilation. Fast compilation will generally be achieved at the expense of run-time performance
633
        /// and quality of diagnostics. Fast compilation is a good trade-off if (a) the stylesheet is known to be correct,
634
        /// and (b) once compiled, it is only executed once against a document of modest size.
635
		/// </summary>
636
		/// <remarks>
637
        /// <para>Fast compilation may result in static errors going unreported, especially if they occur in code
638
        /// that is never executed.</para>
639
        /// <para><i>The current implementation is equivalent to switching off all optimizations other than just-in-time
640
        /// compilation of template rules. Setting this option, however, indicates an intent rather than a mechanism,
641
        /// and the implementation details may change in future to reflect the intent.</i></para>
642
        /// <para>Set to true to request fast compilation; set to false to revert to the optimization options
643
		/// defined in the Configuration.</para>
644
		/// </remarks>
645

    
646
        public bool FastCompliation {
647

    
648
            set { xsltCompiler.setFastCompilation(value); }
649
            get { return xsltCompiler.isFastCompilation(); }
650
        }
651

    
652
        /// <summary>
653
		/// Compile a stylesheet supplied as a <c>TextReader</c>.
654
        /// </summary>
655
        /// <example>
656
        /// <code>
657
        /// String ss = "<![CDATA[<xsl:stylesheet version='2.0'>....</xsl:stylesheet>]]>";
658
        /// TextReader source = new StringReader(ss);
659
        /// XsltExecutable q = compiler.Compile(source);
660
        /// source.Close();
661
        /// </code>
662
        /// </example>
663
        /// <param name="input">A <c>TextReader</c> containing the source text of the stylesheet</param>
664
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
665
		/// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
666
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
667
        /// once it has been compiled.</returns>
668
        /// <remarks>
669
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
670
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
671
        /// <para>The stylesheet is contained in the part of the input stream between its current
672
        /// position and the end of the stream. It is the caller's responsibility to close the 
673
        /// <c>TextReader</c> after use. If the compilation succeeded, then on exit the stream will be 
674
        /// exhausted; if compilation failed, the current position of the stream on exit is
675
        /// undefined.</para>
676
        /// </remarks>
677

    
678
        public XsltExecutable Compile(TextReader input)
679
        {
680
            try {
681
                JStreamSource ss = new JStreamSource(new JDotNetReader(input));
682
                if (baseUri != null)
683
                {
684
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
685
                }
686

    
687
                return new XsltExecutable(xsltCompiler.compile(ss));
688
            }
689
            catch (JSaxonApiException ex) {
690
                throw new StaticError(ex);
691
            }
692
        }
693

    
694
        /// <summary>
695
        /// Compile a stylesheet, retrieving the source using a URI.
696
        /// </summary>
697
        /// <remarks>
698
        /// The document located via the URI is parsed using the <c>System.Xml</c> parser. This
699
        /// URI is used as the base URI of the stylesheet: the <c>BaseUri</c> property of the
700
        /// <c>Compiler</c> is ignored.
701
        /// </remarks>
702
        /// <param name="uri">The URI identifying the location where the stylesheet document can be
703
        /// found</param>
704
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
705
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
706
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
707
        /// once it has been compiled.</returns>
708

    
709
        public XsltExecutable Compile(Uri uri)
710
        {
711
            Object obj = XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
712
            if (obj is Stream)
713
            {
714

    
715
                // See bug issue #2306
716
                return Compile((Stream)obj, uri.ToString(), true);
717

    
718
            }
719
            else
720
            {
721
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
722
            }
723
        }
724

    
725
        /// <summary>
726
		/// Compile a stylesheet, delivered using an <c>XmlReader</c>.
727
        /// </summary>
728
        /// <remarks>
729
		/// <para>
730
        /// The <c>XmlReader</c> is responsible for parsing the document; this method builds a tree
731
        /// representation of the document (in an internal Saxon format) and compiles it.
732
        /// The <c>XmlReader</c> will be used as supplied; it is the caller's responsibility to
733
        /// ensure that the settings of the <c>XmlReader</c> are consistent with the requirements
734
        /// of the XSLT specification (for example, that entity references are expanded and whitespace
735
        /// is preserved).
736
		/// </para>
737
		/// <para>
738
        /// If the <c>XmlReader</c> has a <c>BaseUri</c> property, then that property determines
739
        /// the base URI of the stylesheet module, which is used when resolving any <c>xsl:include</c>
740
        /// or <c>xsl:import</c> declarations. If the <c>XmlReader</c> has no <c>BaseUri</c>
741
        /// property, then the <c>BaseUri</c> property of the <c>Compiler</c> is used instead.
742
        /// An <c>ArgumentNullException</c> is thrown if this property has not been supplied.
743
		/// </para>
744
        /// </remarks>
745
        /// <param name="reader">The XmlReader (that is, the XML parser) used to supply the document containing
746
        /// the principal stylesheet module.</param>
747
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
748
        /// The XsltExecutable may be run as many times as required, in the same or a different
749
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
750
        /// once it has been compiled.</returns>
751

    
752

    
753
        public XsltExecutable Compile(XmlReader reader)
754
        {
755
            JDotNetPullProvider pp = new JDotNetPullProvider(reader);
756
            JPipelineConfiguration pipe = processor.Implementation.makePipelineConfiguration();
757
            pp.setPipelineConfiguration(pipe);
758
            // pp = new PullTracer(pp);  /* diagnostics */
759
            JPullSource source = new JPullSource(pp);
760
            String baseu = reader.BaseURI;
761
            if (baseu == null || baseu == String.Empty)
762
            {
763
                // if no baseURI is supplied by the XmlReader, use the one supplied to this Compiler
764
                if (baseUri == null)
765
                {
766
                    throw new ArgumentNullException("BaseUri");
767
                }
768
                baseu = Uri.EscapeUriString(baseUri.ToString());
769
                pp.setBaseURI(baseu);
770
            }
771
            source.setSystemId(baseu);
772
            try {
773
                return new XsltExecutable(xsltCompiler.compile(source));
774
            }
775
            catch (JSaxonApiException e) {
776
                throw new StaticError(e);
777
            }
778

    
779
            }
780

    
781
        /// <summary>
782
		/// Compile a stylesheet, located at an <c>XdmNode</c>. This may be a document node whose
783
        /// child is an <c>xsl:stylesheet</c> or <c>xsl:transform</c> element, or it may be
784
        /// the <c>xsl:stylesheet</c> or <c>xsl:transform</c> element itself.
785
        /// </summary>
786
        /// <param name="node">The document node or the outermost element node of the document
787
        /// containing the principal stylesheet module.</param>
788
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
789
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
790
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
791
        /// once it has been compiled.</returns>
792

    
793
        public XsltExecutable Compile(XdmNode node)
794
        {
795
            return new XsltExecutable(xsltCompiler.compile(node.Implementation));
796
        }
797

    
798
        /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
799
        /// processing instruction within a source document.
800
        /// </summary>
801
        /// <param name="source">The document node of the source document containing the
802
        /// xml-stylesheet processing instruction.</param>
803
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
804
        /// <remarks>There are some limitations in the current implementation. The media type
805
        /// is ignored, as are the other parameters of the xml-stylesheet instruction. The
806
		/// <c>href</c> attribute must either reference an embedded stylesheet within the same
807
        /// document or a non-embedded external stylesheet.</remarks>
808

    
809
        public XsltExecutable CompileAssociatedStylesheet(XdmNode source)
810
        {
811
            // TODO: lift the restrictions
812
            if (source == null || source.NodeKind != XmlNodeType.Document)
813
            {
814
                throw new ArgumentException("Source must be a document node");
815
            }
816
            IEnumerator kids = source.EnumerateAxis(XdmAxis.Child);
817
            QName xmlstyle = new QName("", "xml-stylesheet");
818
            while (kids.MoveNext())
819
            {
820
                XdmNode n = (XdmNode)kids.Current;
821
                if (n.NodeKind == XmlNodeType.ProcessingInstruction &&
822
                    n.NodeName.Equals(xmlstyle))
823
                {
824
                    // TODO: check the media type
825
                    String href = JProcInstParser.getPseudoAttribute(n.StringValue, "href");
826
                    if (href == null)
827
                    {
828
                        throw new DynamicError("xml-stylesheet processing instruction has no href attribute");
829
                    }
830
                    String fragment = null;
831
                    int hash = href.LastIndexOf('#');
832
                    if (hash == 0)
833
                    {
834
                        if (href.Length == 1)
835
                        {
836
                            throw new DynamicError("Relative URI of '#' is invalid");
837
                        }
838
                        fragment = href.Substring(1);
839
                        JNodeInfo target = ((JTreeInfo)source.value).selectID(fragment, true);
840
                        XdmNode targetWrapper = null;
841
                        if (target == null)
842
                        {
843
                            // There's a problem here because the Microsoft XML parser doesn't
844
                            // report id values, so selectID() will never work. We work around that
845
                            // by looking for an attribute named "id" appearing on an xsl:stylesheet
846
                            // or xsl:transform element
847
                            QName qid = new QName("", "id");
848
                            IEnumerator en = source.EnumerateAxis(XdmAxis.Descendant);
849
                            while (en.MoveNext())
850
                            {
851
                                XdmNode x = (XdmNode)en.Current;
852
                                if (x.NodeKind == XmlNodeType.Element &&
853
                                        x.NodeName.Uri == "http://www.w3.org/1999/XSL/Transform" &&
854
                                        (x.NodeName.LocalName == "stylesheet" || x.NodeName.LocalName == "transform" &&
855
                                        x.GetAttributeValue(qid) == fragment))
856
                                {
857
                                    targetWrapper = x;
858
                                }
859
                            }
860
                        }
861
                        else
862
                        {
863
                            targetWrapper = (XdmNode)XdmValue.Wrap(target);
864
                            targetWrapper.SetProcessor(processor);
865
                        }
866
                        if (targetWrapper == null)
867
                        {
868
                            throw new DynamicError("No element with id='" + fragment + "' found");
869
                        }
870
                        return Compile(targetWrapper);
871
                    }
872
                    else if (hash > 0)
873
                    {
874
                        throw new NotImplementedException("href cannot identify an embedded stylesheet in a different document");
875
                    }
876
                    else
877
                    {
878
                        Uri uri = new Uri(n.BaseUri, href);
879
                        return Compile(uri);
880
                    }
881
                }
882
            }
883
            throw new DynamicError("xml-stylesheet processing instruction not found");
884
        }
885
    }
886

    
887
    /// <summary>
888
    /// An <c>XsltExecutable</c> represents the compiled form of a stylesheet. To execute the stylesheet,
889
	/// it must first be loaded to form an <see cref="XsltTransformer"/> or <see cref="Xslt30Transformer"/>.
890
    /// </summary>
891
    /// <remarks>
892
    /// <para>An <c>XsltExecutable</c> is immutable, and therefore thread-safe. It is simplest to
893
    /// load a new <c>XsltEvaluator</c> each time the stylesheet is to be run. However, the 
894
    /// <c>XsltEvaluator</c> is serially reusable within a single thread.</para>
895
    /// <para>An <c>XsltExecutable</c> is created by using one of the <c>Compile</c>
896
	/// methods on the <see cref="XsltCompiler"/> class.</para>
897
    /// </remarks>    
898

    
899
    [Serializable]
900
    public class XsltExecutable
901
    {
902

    
903
       // private JPreparedStylesheet pss;
904
        //private Processor processor;
905
        private JXsltExecutable executable;
906

    
907
        // internal constructor
908

    
909
        internal XsltExecutable(JXsltExecutable executable)
910
        {
911
            //this.processor = proc;
912
            this.executable = executable;
913
        }
914

    
915
        /// <summary>
916
        /// Load the stylesheet to prepare it for execution.
917
        /// </summary>
918
        /// <returns>
919
        /// An <c>XsltTransformer</c>. The returned <c>XsltTransformer</c> can be used to
920
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
921
        /// </returns>
922

    
923
        public XsltTransformer Load()
924
        {
925
           // JXsltController c = pss.newController();
926
            return new XsltTransformer(executable.load());
927
        }
928

    
929

    
930

    
931
        /// <summary>
932
		/// Load the stylesheet to prepare it for execution. This version of the <c>load()</c> method
933
        /// creates an <code>Xslt30Transformer</code> which offers interfaces for stylesheet
934
        /// invocation corresponding to those described in the XSLT 3.0 specification. It can be used
935
        /// with XSLT 2.0 or XSLT 3.0 stylesheets, and in both cases it offers new XSLT 3.0 functionality such
936
        /// as the ability to supply parameters to the initial template, or the ability to invoke
937
        /// stylesheet-defined functions, or the ability to return an arbitrary sequence as a result
938
        /// without wrapping it in a document node.
939
        /// </summary>
940
        /// <returns>
941
        /// An <c>Xslt30Transformer</c>. The returned <c>Xslt30Transformer</c> can be used to
942
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
943
        /// </returns>
944

    
945
        public Xslt30Transformer Load30()
946
        {
947
            return new Xslt30Transformer(executable.load30());
948
        }
949

    
950
        /// <summary>
951
        /// Output an XML representation of the compiled code of the stylesheet, for purposes of 
952
        /// diagnostics and instrumentation.
953
        /// </summary>
954
        /// <param name="destination">The destination for the diagnostic output</param>
955

    
956
        public void Explain(XmlDestination destination)
957
        {
958
            executable.explain(destination.GetUnderlyingDestination());
959
        }
960

    
961
        /// <summary>
962
        /// Escape hatch to the underlying Java implementation object.
963
        /// </summary>
964

    
965
        public JXsltExecutable Implementation
966
        {
967
            get
968
            {
969
                return executable;
970
            }
971
        }
972

    
973
        /// <summary>
974
        /// Get the whitespace stripping policy defined by this stylesheet, that is, the policy
975
        /// defined by the <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> elements in the stylesheet.
976
        /// </summary>
977
        /// <returns> a newly constructed <c>WhitespacePolicy</c> based on the declarations in this
978
        /// stylesheet. This policy can be used as input to a <see cref="DocumentBuilder"/>.</returns>
979
        
980
        public WhitespacePolicy getWhitespaceStrippingPolicy() {
981
            return new WhitespacePolicy(executable);
982
        }
983

    
984

    
985
        /// <summary>
986
        /// Get the names of the <c>xsl:param</c> elements defined in this stylesheet, with details
987
        /// of each parameter including its required type, and whether it is required or optional.
988
        /// </summary>
989
        /// <returns>
990
		/// a <c>Dictionary</c> whose keys are the names of global parameters in the stylesheet,
991
		/// and whose values are <see cref="Saxon.Api.XsltExecutable+ParameterDetails"/> objects giving information about the
992
        /// corresponding parameter.
993
        /// </returns>
994

    
995
        public Dictionary<QName, ParameterDetails> GetGlobalParameters()
996
        {
997
            java.util.HashMap globals = executable.getGlobalParameters();
998
            Dictionary<QName, ParameterDetails> params1 = new Dictionary<QName, ParameterDetails>();
999
            int count = globals.size();
1000
            object[] names = globals.keySet().toArray();
1001
            for (int i = 0; i < count; i++) {
1002
                JXsltExecutable.ParameterDetails details = (JXsltExecutable.ParameterDetails)globals.get(names[i]);
1003
                XdmSequenceType sType = XdmSequenceType.FromSequenceType(details.getUnderlyingDeclaredType());
1004
                sType.itemType.SetJXdmItemType(details.getDeclaredItemType());
1005
                params1.Add(new QName((net.sf.saxon.s9api.QName)names[i]), new ParameterDetails(sType, false));
1006

    
1007
            }
1008
            return params1;
1009
        }
1010

    
1011
        /// <summary>
1012
        /// Information about a global parameter to a stylesheet.
1013
        /// </summary>
1014

    
1015
        public class ParameterDetails
1016
        {
1017
            private XdmSequenceType type;
1018
            private bool isRequired;
1019

    
1020
            /// <summary>
1021
            /// Create parameter details.
1022
            /// </summary>
1023
            /// <param name="type">The declared type of the parameter.</param>
1024
            /// <param name="isRequired">Indicates whether the parameter is required or optional.</param>
1025
            
1026
            public ParameterDetails(XdmSequenceType type, bool isRequired)
1027
            {
1028
                this.type = type;
1029
                this.isRequired = isRequired;
1030
            }
1031

    
1032
            /// <summary>
1033
            /// Gets the declared item type of the parameter.
1034
            /// </summary>
1035
            /// <returns>The type defined in the <code>as</code> attribute of the <code>xsl:param</code> element,
1036
            /// without its occurrence indicator</returns>
1037
            public XdmItemType GetDeclaredItemType()
1038
            {
1039
                return type.itemType;
1040
            }
1041

    
1042

    
1043
            /// <summary>
1044
            /// Gets the declared cardinality of the parameter.
1045
            /// </summary>
1046
            /// <returns>The occurrence indicator from the type appearing in the <code>as</code> attribute
1047
            /// of the <code>xsl:param</code> element</returns>
1048

    
1049
            public char GetDeclaredCardinality()
1050
            {
1051
                return type.occurrenceIn;
1052
            }
1053

    
1054
            /// <summary>
1055
            /// Gets the underlying declared type of the parameter.
1056
            /// </summary>
1057
            /// <returns>The underlying declared type.</returns>
1058

    
1059
            public XdmSequenceType GetUnderlyingDeclaredType()
1060
            {
1061
                return type;
1062
            }
1063

    
1064

    
1065
            /// <summary>
1066
            /// Ask whether the parameter is required (mandatory) or optional
1067
            /// </summary>
1068
            /// <returns><c>true</c> if the parameter is mandatory (<code>required="yes"</code>), false
1069
            /// if it is optional.</returns>
1070

    
1071
            public bool IsRequired
1072
            {
1073
                set { this.isRequired = value; }
1074
                get { return this.isRequired; }
1075

    
1076
            }
1077
        }
1078

    
1079

    
1080

    
1081

    
1082
    }
1083

    
1084

    
1085
    /// <summary inherits="XdmDestination">
1086
    /// An <c>XsltTransformer</c> represents a compiled and loaded stylesheet ready for execution.
1087
    /// The <c>XsltTransformer</c> holds details of the dynamic evaluation context for the stylesheet.
1088
    /// </summary>
1089
    /// <remarks>
1090
    /// <para>An <c>XsltTransformer</c> must not be used concurrently in multiple threads. It is safe,
1091
    /// however, to reuse the object within a single thread to run the same stylesheet several times.
1092
    /// Running the stylesheet does not change the context that has been established.</para>
1093
    /// <para>An <c>XsltTransformer</c> is always constructed by running the <c>Load</c> method of
1094
    /// an <c>XsltExecutable</c>.</para>
1095
	/// <para>The <see cref="Xslt30Transformer"/> class provides invocation options that are more closely aligned
1096
    /// with the XSLT 3.0 specification, for example streamed evaluation. However, both <c>XsltTransformer</c> 
1097
	/// and <c>Xslt30Transformer</c> can be used irrespective of the XSLT language version used in the stylesheet.</para>
1098
    /// </remarks>
1099

    
1100
    [Serializable]
1101
    public class XsltTransformer : XmlDestination
1102
    {
1103

    
1104
        /* private JXsltController controller;
1105
      
1106
         private JStreamSource streamSource;
1107
         private GlobalParameterSet globalParameters;
1108
         private bool baseOutputUriWasSet = false;*/
1109
        private XmlDestination destination;
1110
        private StandardLogger traceFunctionDestination;
1111
        private IMessageListener messageListener;
1112
        private IMessageListener2 messageListener2;
1113
        private IResultDocumentHandler resultDocumentHandler;
1114
        private QName initialTemplateName;
1115
        private XdmNode initialContextNode;
1116
        private JXsltTransformer transformer;
1117

    
1118
        // internal constructor
1119

    
1120
        internal XsltTransformer(JXsltTransformer transformer)
1121
        {
1122
            this.transformer = transformer;
1123
        }
1124

    
1125
        /// <summary>
1126
        /// The global context item for the stylesheet, as a node.
1127
        /// </summary>
1128
        /// <remarks><para>Although XSLT 3.0 allows the global context item to be any item,
1129
        /// this interface only allows it to be a node.
1130
        /// Most commonly it will be a document node, which might be constructed
1131
        /// using the <c>Build</c> method of the <c>DocumentBuilder</c> object.</para>
1132
        /// <para>Note that this can be inefficient if the stylesheet uses <c>xsl:strip-space</c>
1133
        /// to strip whitespace, or <c>input-type-annotations="strip"</c> to remove type
1134
        /// annotations, since this will result in the transformation operating on a virtual document
1135
        /// implemented as a view or wrapper of the supplied document.</para>
1136
        /// </remarks>
1137

    
1138
        public XdmNode InitialContextNode
1139
        {
1140
            get {
1141
                JNodeInfo node = transformer.getInitialContextNode().getUnderlyingNode();
1142
                return node == null ? null : ((XdmNode)XdmValue.Wrap(node)); }
1143
            set { transformer.setInitialContextNode(value == null ? null : (net.sf.saxon.s9api.XdmNode)XdmValue.FromGroundedValueToJXdmValue(value.value)); }
1144
        }
1145

    
1146
        /// <summary>
1147
        /// Supply the principal input document for the transformation in the form of a stream.
1148
        /// </summary>
1149
        /// <remarks>
1150
        /// <para>If this method is used, the <c>InitialContextNode</c> is ignored.</para>
1151
        /// <para>The supplied stream will be consumed by the <c>Run()</c> method.
1152
        /// Closing the input stream after use is the client's responsibility.</para>
1153
        /// <para>A base URI must be supplied in all cases. It is used to resolve relative
1154
        /// URI references appearing within the input document.</para>
1155
        /// <para>Schema validation is applied to the input document according to the value of
1156
        /// the <c>SchemaValidationMode</c> property.</para>
1157
        /// <para>Whitespace stripping is applied according to the value of the
1158
        /// <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> declarations in the stylesheet.</para>
1159
        /// </remarks>
1160
        /// <param name="input">
1161
        /// The stream containing the source code of the principal input document to the transformation. The document
1162
        /// node at the root of this document will be the global context item for the transformation.
1163
        /// </param>
1164
        /// <param name="baseUri">
1165
        /// The base URI of the principal input document. This is used for example by the <c>document()</c>
1166
        /// function if the document contains links to other documents in the form of relative URIs.</param>
1167

    
1168
        public void SetInputStream(Stream input, Uri baseUri)
1169
        {
1170
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
1171
            transformer.setSource(streamSource);
1172
        }
1173

    
1174
        /// <summary>
1175
		/// The initial mode for the stylesheet. This is either a <c>QName</c>, for a 
1176
        /// specific mode, or null, for the default mode.
1177
        /// </summary>
1178
        /// <remarks>
1179
        /// The default mode will usually be the unnamed mode, but if the stylesheet declares a
1180
        /// named mode as the default mode, then supplying null as the <c>InitialMode</c> invokes this default.
1181
        /// </remarks>
1182

    
1183
        public QName InitialMode
1184
        {
1185
            get
1186
            {
1187
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
1188
                if (mode == null)
1189
                {
1190
                    return null;
1191
                }
1192

    
1193
                return QName.FromClarkName(mode.getClarkName());
1194
            }
1195
            set
1196
            {
1197
               transformer.setInitialMode(value == null ? null : net.sf.saxon.s9api.QName.fromEQName(value.EQName));
1198
            }
1199
        }
1200

    
1201

    
1202
        /// <summary>
1203
		/// The initial template for the stylesheet. This is either a <c>QName</c>, for a 
1204
        /// named template, or null, if no initial template has been set.
1205
        /// </summary>
1206
        /// <remarks>
1207
        /// If the stylesheet is to be invoked by calling the template named <c>xsl:initial-template</c>,
1208
		/// then the <c>InitialTemplate</c> property should be set to this <c>QName</c> explicitly.
1209
        /// </remarks>
1210
        /// <exception cref="DynamicError">Setting this property to the name of a template
1211
		/// that does not exist in the stylesheet throws a <c>DynamicError</c> with error 
1212
        /// code XTDE0040. Setting it to the name of a template that has template
1213
		/// parameters throws a <c>DynamicError</c> with error code XTDE0060.</exception>
1214

    
1215
        public QName InitialTemplate
1216
        {
1217
            get
1218
            {
1219
                return initialTemplateName;
1220
            }
1221
            set
1222
            {
1223
                initialTemplateName = value;
1224
                transformer.setInitialTemplate(initialTemplateName.UnderlyingQName());
1225
            }
1226
        }
1227

    
1228
        /// <summary>
1229
        /// The base output URI, which acts as the base URI for resolving the <c>href</c>
1230
        /// attribute of <c>xsl:result-document</c>.
1231
        /// </summary>
1232

    
1233
        public Uri BaseOutputUri
1234
        {
1235
            get
1236
            {
1237
                return new Uri(transformer.getBaseOutputURI());
1238
            }
1239
            set
1240
            {
1241
                transformer.setBaseOutputURI(value.ToString());
1242
            }
1243
        }
1244

    
1245

    
1246
        /// <summary>
1247
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
1248
        /// loaded using the <c>doc()</c>, <c>document()</c>, or <c>collection()</c> functions.
1249
        /// </summary>
1250

    
1251
        public SchemaValidationMode SchemaValidationMode
1252
        {
1253
            get
1254
            {
1255
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
1256
                {
1257
                    case JValidation.STRICT:
1258
                        return SchemaValidationMode.Strict;
1259
                    case JValidation.LAX:
1260
                        return SchemaValidationMode.Lax;
1261
                    case JValidation.STRIP:
1262
                        return SchemaValidationMode.None;
1263
                    case JValidation.PRESERVE:
1264
                        return SchemaValidationMode.Preserve;
1265
                    case JValidation.DEFAULT:
1266
                    default:
1267
                        return SchemaValidationMode.Unspecified;
1268
                }
1269
            }
1270

    
1271
            set
1272
            {
1273
                switch (value)
1274
                {
1275
                    case SchemaValidationMode.Strict:
1276
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
1277
                        break;
1278
                    case SchemaValidationMode.Lax:
1279
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
1280
                        break;
1281
                    case SchemaValidationMode.None:
1282
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
1283
                        break;
1284
                    case SchemaValidationMode.Preserve:
1285
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
1286
                        break;
1287
                    case SchemaValidationMode.Unspecified:
1288
                    default:
1289
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
1290
                        break;
1291
                }
1292
            }
1293
        }
1294

    
1295

    
1296

    
1297

    
1298

    
1299
        /// <summary>
1300
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
1301
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
1302
        /// </summary>
1303

    
1304
        public XmlResolver InputXmlResolver
1305
        {
1306
            get
1307
            {
1308
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
1309
            }
1310
            set
1311
            {
1312
                transformer.setURIResolver(new JDotNetURIResolver(value));
1313
            }
1314
        }
1315

    
1316
        /// <summary>
1317
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
1318
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
1319
        /// attribute.
1320
        /// </summary>
1321
        /// <remarks>
1322
        /// In the absence of a user-supplied result document handler, the <c>href</c>
1323
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
1324
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
1325
        /// and the resulting absolute URI must identify a writable resource (typically
1326
        /// a file in filestore, using the <c>file:</c> URI scheme).
1327
        /// </remarks>
1328

    
1329
        public IResultDocumentHandler ResultDocumentHandler
1330
        {
1331
            get
1332
            {
1333
                return resultDocumentHandler;
1334
            }
1335
            set
1336
            {
1337
                resultDocumentHandler = value;
1338
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
1339
            }
1340
        }
1341

    
1342
        /// <summary>
1343
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1344
		/// </summary>
1345
		/// <remarks> 
1346
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1347
        /// the processor will then invoke the listener once for each message generated during
1348
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1349
        /// representing a document node.</para>
1350
        /// <para>If no message listener is supplied by the caller, message information will be written to
1351
        /// the standard error stream.</para>
1352
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1353
        /// on the message object will usually generate an acceptable representation of the
1354
        /// message.</para>
1355
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1356
        /// the message is first notified using this interface, and then an exception is thrown
1357
        /// which terminates the transformation.</para>
1358
        /// </remarks>
1359

    
1360
        public IMessageListener MessageListener
1361
        {
1362
            set
1363
            {
1364
                messageListener = value;
1365
                transformer.setMessageListener(new MessageListenerProxy(value));
1366
            }
1367
            get
1368
            {
1369
                return messageListener;
1370
            }
1371
        }
1372

    
1373

    
1374

    
1375
        /// <summary>
1376
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1377
        /// </summary>
1378
        /// <remarks> 
1379
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1380
        /// the processor will then invoke the listener once for each message generated during
1381
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1382
        /// representing a document node.</para>
1383
        /// <para>If no message listener is supplied by the caller, message information will be written to
1384
        /// the standard error stream.</para>
1385
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1386
        /// on the message object will usually generate an acceptable representation of the
1387
        /// message.</para>
1388
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1389
        /// the message is first notified using this interface, and then an exception is thrown
1390
        /// which terminates the transformation.</para>
1391
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
1392
        /// in allowing the error code supplied to xsl:message to be notified</para>
1393
        /// </remarks>
1394

    
1395
        public IMessageListener2 MessageListener2
1396
        {
1397
            set
1398
            {
1399
                messageListener2 = value;
1400
                transformer.setMessageListener(new MessageListenerProxy2(value));
1401
            }
1402
            get
1403
            {
1404
                return messageListener2;
1405
            }
1406
        }
1407

    
1408
        /// <summary>
1409
        /// Destination for output of messages using the <c>trace()</c> function.
1410
        /// </summary>
1411
		/// <remarks> 
1412
		/// <para>If no message listener is supplied by the caller, message information will be written to
1413
		/// the standard error stream.</para>
1414
        /// <para>The supplied destination is ignored if a <c>TraceListener</c> is in use.</para>
1415
        /// </remarks>
1416

    
1417
        public StandardLogger TraceFunctionDestination
1418
        {
1419
            set
1420
            {
1421
                traceFunctionDestination = value;
1422
                transformer.setTraceFunctionDestination(value);
1423
            }
1424
            get
1425
            {
1426
                return traceFunctionDestination;
1427
            }
1428
        }
1429

    
1430

    
1431

    
1432
        /// <summary>
1433
        /// Set the value of a stylesheet parameter.
1434
        /// </summary>
1435
        /// <param name="name">The name of the parameter, expressed
1436
        /// as a QName. If a parameter of this name has been declared in the
1437
        /// stylesheet, the given value will be assigned to the variable. If the
1438
        /// variable has not been declared, calling this method has no effect (it is
1439
        /// not an error).</param>
1440
        /// <param name="value">The value to be given to the parameter.
1441
        /// If the parameter declaration defines a required type for the variable, then
1442
        /// this value will be converted in the same way as arguments to function calls
1443
        /// (for example, numeric promotion is applied).</param>
1444

    
1445
        public void SetParameter(QName name, XdmValue value)
1446
        {
1447
            transformer.setParameter(net.sf.saxon.s9api.QName.fromEQName(name.EQName), net.sf.saxon.s9api.XdmValue.wrap(value.value));
1448
        }
1449

    
1450

    
1451

    
1452
        /// <summary>
1453
		/// The destination for the result of the transformation. The class <c>XmlDestination</c> is an abstraction 
1454
        /// that allows a number of different kinds of destination to be specified.
1455
        /// </summary>
1456
        /// <remarks>
1457
        /// <para>The Destination can be used to chain transformations into a pipeline, by using one
1458
        /// <c>XsltTransformer</c> as the destination of another.</para>
1459
        /// </remarks>
1460

    
1461
        public XmlDestination Destination
1462
        {
1463
            get
1464
            {
1465
                return this.destination;
1466
            }
1467
            set
1468
            {
1469
                this.destination = value;
1470
                transformer.setDestination(value.GetUnderlyingDestination());
1471
            }
1472

    
1473
        }
1474

    
1475
        public JDestination GetUnderlyingDestination()
1476
        {
1477
            return transformer;
1478
        }
1479

    
1480

    
1481
        /// <summary>
1482
		/// Close the <c>Destination</c>, releasing any resources that need to be released.
1483
        /// </summary>
1484
        /// <remarks>
1485
        /// This method is called by the system on completion of a query or transformation.
1486
		/// Some kinds of <c>Destination</c> may need to close an output stream, others might
1487
        /// not need to do anything. The default implementation does nothing.
1488
        /// </remarks>
1489

    
1490
        public void Close()
1491
        {
1492
            transformer.close();
1493

    
1494
        }
1495

    
1496
		// internal method
1497

    
1498
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
1499
        {
1500

    
1501
            JController controller = transformer.getUnderlyingController();
1502
                JPipelineConfiguration pipe = controller.getConfiguration().makePipelineConfiguration();
1503
                JReceiver r = destination.GetUnderlyingDestination().getReceiver(pipe, controller.getExecutable().getPrimarySerializationProperties());
1504
                pipe.setController(controller);
1505
                return r;
1506
            //}
1507
        }
1508

    
1509
        /// <summary>
1510
        /// Run the transformation, sending the result to a specified destination.
1511
        /// </summary>
1512
        /// <param name="destination">
1513
        /// The destination for the results of the stylesheet. The class <c>XmlDestination</c>
1514
        /// is an abstraction that allows a number of different kinds of destination
1515
        /// to be specified.
1516
        /// </param>
1517
		/// <exception cref="DynamicError">Throws a <c>DynamicError</c> if the transformation
1518
        /// fails.</exception>
1519

    
1520
        public void Run(XmlDestination destination)
1521
        {
1522
            if (destination == null)
1523
            {
1524
                throw new DynamicError("Destination is null");
1525
            }
1526
           
1527
            try
1528
            {
1529
                transformer.setDestination(destination.GetUnderlyingDestination());
1530
                transformer.transform() ;
1531
               
1532
            }
1533
            catch (JSaxonApiException err)
1534
            {
1535
                throw new DynamicError(err);
1536
            }
1537
        }
1538

    
1539
        /*internal void applyTemplatesToSource(JStreamSource streamSource, JReceiver outi){
1540

    
1541
           
1542
            if (controller.getInitialMode().isDeclaredStreamable()) {
1543
                controller.applyStreamingTemplates(streamSource, outi);
1544
            }
1545
        } */
1546

    
1547
        /// <summary>
1548
        /// Escape hatch to the underlying Java implementation
1549
        /// </summary>
1550

    
1551
        public JController Implementation
1552
        {
1553
            get { return transformer.getUnderlyingController(); }
1554
        }
1555

    
1556

    
1557
    }
1558

    
1559
    /// <summary>
1560
	/// <c>RecoveryPolicy</c> is an enumeration of the different actions that can be taken when a "recoverable error" occurs.
1561
    /// </summary>  
1562

    
1563
    public enum RecoveryPolicy
1564
    {
1565
        /// <summary>
1566
        /// Ignore the error, take the recovery action, do not produce any message
1567
        /// </summary>
1568
        RecoverSilently,
1569

    
1570
        /// <summary>
1571
        /// Take the recovery action after outputting a warning message
1572
        /// </summary>
1573
        RecoverWithWarnings,
1574

    
1575
        /// <summary>
1576
        /// Treat the error as fatal
1577
        /// </summary>
1578
        DoNotRecover
1579

    
1580
    }
1581

    
1582

    
1583

    
1584
    /// <summary>An <c>IResultDocumentHandler</c> can be nominated to handle output
1585
    /// produced by the <c>xsl:result-document</c> instruction in an XSLT stylesheet.
1586
    /// </summary>
1587
    /// <remarks>
1588
    /// <para>This interface affects any <c>xsl:result-document</c> instruction
1589
    /// executed by the stylesheet, provided that it has an <c>href</c> attribute.</para> 
1590
    /// <para>If no <c>IResultDocumentHandler</c> is nominated (in the
1591
    /// <c>IResultDocumentHandler</c> property of the <c>XsltTransformer</c>), the output
1592
    /// of <code>xsl:result-document</code> is serialized, and is written to the file
1593
    /// or other resource identified by the URI in the <c>href</c> attribute, resolved
1594
    /// (if it is relative) against the URI supplied in the <c>BaseOutputUri</c> property
1595
    /// of the <c>XsltTransformer</c>.</para>
1596
    /// <para>If an <c>IResultDocumentHandler</c> is nominated, however, its
1597
    /// <c>HandleResultDocument</c> method will be called whenever an <c>xsl:result-document</c>
1598
    /// instruction with an <c>href</c> attribute is evaluated, and the generated result tree
1599
    /// will be passed to the <c>XmlDestination</c> returned by that method.</para> 
1600
    /// </remarks>
1601

    
1602
    public interface IResultDocumentHandler
1603
    {
1604

    
1605
        /// <summary> Handle output produced by the <c>xsl:result-document</c>
1606
        /// instruction in an XSLT stylesheet. This method is called by the XSLT processor
1607
        /// when an <c>xsl:result-document</c> with an <c>href</c> attribute is evaluated.
1608
        /// </summary>
1609
        /// <param name="href">An absolute or relative URI. This will be the effective value of the 
1610
        /// <c>href</c> attribute of the <c>xsl:result-document</c> in the stylesheet.</param>
1611
        /// <param name="baseUri">The base URI that should be used for resolving the value of
1612
        /// <c>href</c> if it is relative. This will always be the value of the <c>BaseOutputUri</c>
1613
        /// property of the <c>XsltTransformer</c>.</param>
1614
        /// <returns>An <c>XmlDestination</c> to handle the result tree produced by the
1615
        /// <c>xsl:result-document</c> instruction. The <c>Close</c> method of the returned
1616
        /// <c>XmlDestination</c> will be called when the output is complete.</returns>
1617
        /// <remarks>
1618
        /// <para>The XSLT processor will ensure that the stylesheet cannot create
1619
        /// two distinct result documents which are sent to the same URI. It is the responsibility
1620
        /// of the <c>IResultDocumentHandler</c> to ensure that two distinct result documents are
1621
        /// not sent to the same <c>XmlDestination</c>. Failure to observe this rule can result
1622
        /// in output streams being incorrectly closed.
1623
        /// </para>
1624
        /// <para>Note that more than one result document can be open at the same time,
1625
        /// and that the order of opening, writing, and closing result documents chosen
1626
        /// by the processor does not necessarily bear any direct resemblance to the way
1627
        /// that the XSLT source code is written.</para></remarks>
1628

    
1629
        /**public**/
1630
        XmlDestination HandleResultDocument(string href, Uri baseUri);
1631

    
1632
    }
1633

    
1634
    ///<summary>Internal wrapper class for <c>IResultDocumentHandler</c></summary>
1635
    internal class ResultDocumentHandlerWrapper : JResultDocumentResolver
1636
    {
1637

    
1638
        private IResultDocumentHandler handler;
1639
        private ArrayList resultList = new ArrayList();
1640
        private ArrayList destinationList = new ArrayList();
1641
        private JPipelineConfiguration pipe;
1642

    
1643
        /// <summary>
1644
        /// Initializes a new instance of the <see cref="Saxon.Api.ResultDocumentHandlerWrapper"/> class.
1645
        /// </summary>
1646
        /// <param name="handler">Handler.</param>
1647
        /// <param name="pipe">Pipe.</param>
1648
        public ResultDocumentHandlerWrapper(IResultDocumentHandler handler, JPipelineConfiguration pipe)
1649
        {
1650
            this.handler = handler;
1651
            this.pipe = pipe;
1652
        }
1653

    
1654

    
1655

    
1656

    
1657
        /// <summary>
1658
        /// Close the specified result.
1659
        /// </summary>
1660
        /// <param name="result">Result.</param>
1661
        public void close(JResult result)
1662
        {
1663
            for (int i = 0; i < resultList.Count; i++)
1664
            {
1665
                if (Object.ReferenceEquals(resultList[i], result))
1666
                {
1667
                    ((XmlDestination)destinationList[i]).GetUnderlyingDestination().close();
1668
                    resultList.RemoveAt(i);
1669
                    destinationList.RemoveAt(i);
1670
                    return;
1671
                }
1672
            }
1673
        }
1674

    
1675
        /// <summary>
1676
        /// Resolve the specified href and baseString.
1677
        /// </summary>
1678
        /// <param name="href">Href.</param>
1679
        /// <param name="baseString">Base string.</param>
1680
        public JReceiver resolve(net.sf.saxon.expr.XPathContext xpc, string href, string baseString, net.sf.saxon.serialize.SerializationProperties sp)
1681
        {
1682
            Uri baseUri;
1683
            try
1684
            {
1685
                baseUri = new Uri(baseString);
1686
            }
1687
            catch (System.UriFormatException err)
1688
            {
1689
                throw new JTransformerException("Invalid base output URI " + baseString, err);
1690
            }
1691
            XmlDestination destination = handler.HandleResultDocument(href, baseUri);
1692
            JReceiver result = destination.GetUnderlyingDestination().getReceiver(pipe, sp);
1693
            resultList.Add(result);
1694
            destinationList.Add(destination);
1695
            return result;
1696
        }
1697
    }
1698

    
1699
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1700
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1701
    /// </summary>
1702
    /// <remarks>
1703
    /// <para>This interface affects any <c>xsl:message</c> instruction
1704
    /// executed by the stylesheet.</para> 
1705
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1706
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1707
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1708
    /// output stream.</para>
1709
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1710
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1711
    /// instruction is evaluated.</para> 
1712
    /// </remarks>
1713

    
1714
    public interface IMessageListener
1715
    {
1716

    
1717
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1718
        /// in the stylesheet
1719
        /// </summary>
1720
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1721
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1722
        /// <c>GetStringValue()</c></param>
1723
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1724
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1725
        /// module and the line number of the <c>xsl:message</c></param>
1726

    
1727
        /**public**/
1728
        void Message(XdmNode content, bool terminate, IXmlLocation location);
1729

    
1730
    }
1731

    
1732

    
1733

    
1734
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1735
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1736
    /// </summary>
1737
    /// <remarks>
1738
    /// <para>This interface affects any <c>xsl:message</c> instruction
1739
    /// executed by the stylesheet.</para> 
1740
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1741
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1742
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1743
    /// output stream.</para>
1744
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1745
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1746
    /// instruction is evaluated.</para> 
1747
    /// <para>The <c>MessageListener2</c> interface differs from <c>MessageListener</c>
1748
    /// in allowing the error code supplied to <c>xsl:message</c> to be made available.</para>
1749
    /// </remarks>
1750

    
1751
    public interface IMessageListener2
1752
    {
1753

    
1754
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1755
        /// in the stylesheet
1756
        /// </summary>
1757
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1758
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1759
        /// <c>GetStringValue()</c></param>
1760
        /// <param name="errorCode">a QName containing the error supplied to the called on xsl:message, or its default of err:XTM9000.</param>
1761
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1762
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1763
        /// module and the line number of the <c>xsl:message</c></param>
1764

    
1765
        /**public**/
1766
        void Message(XdmNode content, QName errorCode,  bool terminate, IXmlLocation location);
1767

    
1768
    }
1769

    
1770
    /// <summary>
1771
    /// An <c>IXmlLocation</c> represents the location of a node within an XML document.
1772
    /// It is in two parts: the base URI (or system ID) of the external entity (which will usually
1773
    /// be the XML document entity itself), and the line number of a node relative
1774
    /// to the base URI of the containing external entity.
1775
    /// </summary>
1776

    
1777
    public interface IXmlLocation
1778
    {
1779

    
1780
        /// <summary>
1781
        /// The base URI (system ID) of an external entity within an XML document.
1782
        /// Set to null if the base URI is not known (for example, for an XML document
1783
        /// created programmatically where no base URI has been set up).
1784
        /// </summary>
1785

    
1786
        /**public**/
1787
        Uri BaseUri { get; set; }
1788

    
1789
        /// <summary>
1790
        /// The line number of a node relative to the start of the external entity.
1791
        /// The value -1 indicates that the line number is not known or not applicable.
1792
        /// </summary>
1793

    
1794
        /**public**/
1795
        int LineNumber { get; set; }
1796
    }
1797

    
1798

    
1799
    /// <summary>
1800
	/// Xml location. An implementation of <c>IXmlLocation</c>.
1801
    /// </summary>
1802
    internal class XmlLocation : IXmlLocation
1803
    {
1804
        private Uri baseUri;
1805
        private int lineNumber;
1806
        public Uri BaseUri
1807
        {
1808
            get { return baseUri; }
1809
            set { baseUri = value; }
1810
        }
1811
        public int LineNumber
1812
        {
1813
            get { return lineNumber; }
1814
            set { lineNumber = value; }
1815
        }
1816
    }
1817

    
1818

    
1819
    /// <summary>
1820
    /// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener</c> that can receive 
1821
    /// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1822
    /// </summary>
1823
    [Serializable]
1824
    internal class MessageListenerProxy : net.sf.saxon.s9api.MessageListener
1825
    {
1826

    
1827
        public IMessageListener listener;
1828

    
1829
        /// <summary>
1830
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1831
        /// </summary>
1832
        /// <param name="ml">ml.</param>
1833
        public MessageListenerProxy(IMessageListener ml)
1834
        {
1835
            listener = ml;
1836
        }
1837

    
1838

    
1839
        public void message(net.sf.saxon.s9api.XdmNode xn, bool b, SourceLocator sl)
1840
        {
1841
            IXmlLocation location = new XmlLocation();
1842
            location.BaseUri = new Uri(sl.getSystemId());
1843
            location.LineNumber = sl.getLineNumber();
1844
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), b, location);
1845
        }
1846
    }
1847

    
1848

    
1849

    
1850
    /// <summary>
1851
	/// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener2</c> that can receive 
1852
	/// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1853
    /// </summary>
1854
    [Serializable]
1855
    internal class MessageListenerProxy2 : net.sf.saxon.s9api.MessageListener2
1856
    {
1857

    
1858
        public IMessageListener2 listener;
1859

    
1860
        /// <summary>
1861
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1862
        /// </summary>
1863
        /// <param name="ml">ml.</param>
1864
        public MessageListenerProxy2(IMessageListener2 ml)
1865
        {
1866
            listener = ml;
1867
        }
1868

    
1869

    
1870
        public void message(net.sf.saxon.s9api.XdmNode xn, net.sf.saxon.s9api.QName qn, bool b, SourceLocator sl)
1871
        {
1872
            IXmlLocation location = new XmlLocation();
1873
            location.BaseUri = new Uri(sl.getSystemId());
1874
            location.LineNumber = sl.getLineNumber();
1875
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), new QName(qn),b, location);
1876
        }
1877
    }
1878

    
1879

    
1880

    
1881
    /// <summary>An <code>Xslt30Transformer</code> represents a compiled and loaded stylesheet ready for execution.
1882
    /// The <code>Xslt30Transformer</code> holds details of the dynamic evaluation context for the stylesheet.</summary>
1883

    
1884
    /// <remarks><para>The <code>Xslt30Transformer</code> differs from <see cref="XsltTransformer"/> 
1885
    /// in supporting new options
1886
    /// for invoking a stylesheet, corresponding to facilities defined in the XSLT 3.0 specification. However,
1887
    /// it is not confined to use with XSLT 3.0, and most of the new invocation facilities (for example,
1888
    /// calling a stylesheet-defined function directly) work equally well with XSLT 2.0 and in some cases
1889
    /// XSLT 1.0 stylesheets.</para>
1890
    /// <para>An <code>Xslt30Transformer</code> must not be used concurrently in multiple threads.
1891
    /// It is safe, however, to reuse the object within a single thread to run the same
1892
    /// stylesheet several times. Running the stylesheet does not change the context
1893
    /// that has been established.</para>
1894

    
1895
    /// <para>An <code>Xslt30Transformer</code> is always constructed by running the <code>Load30</code>
1896
    /// method of an <see cref="XsltExecutable"/>.</para>
1897

    
1898
    /// <para>Unlike <code>XsltTransformer</code>, an <code>Xslt30Transformer</code> is not a <code>Destination</code>.
1899
    /// To pipe the results of one transformation into another, the target should be an <code>XsltTransfomer</code>
1900
    /// rather than an <code>Xslt30Transformer</code>.</para>
1901

    
1902
    /// <para>Evaluation of an Xslt30Transformer proceeds in a number of phases:</para>
1903
    /// <list type="number">
1904
    /// <item>First, values may be supplied for stylesheet parameters and for the global context item. The
1905
    /// global context item is used when initializing global variables. Unlike earlier transformation APIs,
1906
    /// the global context item is quite independent of the "principal source document".
1907
    /// </item>
1908
    /// <item>The stylesheet may now be repeatedly invoked. Each invocation takes
1909
    /// one of three forms:
1910
    /// <list type="number">
1911
    /// <item>Invocation by applying templates. In this case, the information required is (i) an initial
1912
    /// mode (which defaults to the unnamed mode), (ii) an initial match sequence, which is any
1913
    /// XDM value, which is used as the effective "select" expression of the implicit apply-templates
1914
    /// call, and (iii) optionally, values for the tunnel and non-tunnel parameters defined on the
1915
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
1916
    /// <code>apply-templates</code> call).</item>
1917
    /// <item>Invocation by calling a named template. In this case, the information required is
1918
    /// (i) the name of the initial template (which defaults to "xsl:initial-template"), and
1919
    /// (ii) optionally, values for the tunnel and non-tunnel parameters defined on the
1920
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
1921
    /// <code>call-template</code> instruction).</item>
1922
    /// <item>Invocation by calling a named function. In this case, the information required is
1923
    /// the sequence of arguments to the function call.</item>
1924
    /// </list>
1925
    /// </item>
1926
    /// <item>Whichever invocation method is chosen, the result may either be returned directly, as an arbitrary
1927
    /// XDM value, or it may effectively be wrapped in an XML document. If it is wrapped in an XML document,
1928
    /// that document can be processed in a number of ways, for example it can be materialized as a tree in
1929
    /// memory, it can be serialized as XML or HTML, or it can be subjected to further transformation.</item>
1930
    /// </list>
1931
    /// <para>Once the stylesheet has been invoked (using any of these methods), the values of the global context
1932
    /// item and stylesheet parameters cannot be changed. If it is necessary to run another transformation with
1933
    /// a different context item or different stylesheet parameters, a new <c>Xslt30Transformer</c>
1934
    /// should be created from the original <c>XsltExecutable</c>.</para>
1935
    /// <para> @since 9.6</para> 
1936
    /// </remarks>
1937

    
1938
    [Serializable]
1939
    public class Xslt30Transformer
1940
    {
1941

    
1942

    
1943
        private IResultDocumentHandler resultDocumentHandler;
1944
        private StandardLogger traceFunctionDestination;
1945
        private IMessageListener messageListener;
1946
        private IMessageListener2 messageListener2;
1947
        private JXslt30Transformer transformer;
1948

    
1949
		// internal constructor
1950

    
1951
        internal Xslt30Transformer(JXslt30Transformer transformer)
1952
        {
1953

    
1954
            this.transformer = transformer;
1955
            //this.globalParameterSet = new GlobalParameterSet(globalParameters);
1956
        }
1957

    
1958

    
1959
        /// <summary> Supply the context item to be used when evaluating global variables and parameters.
1960
        /// This argument can be null if no context item is to be supplied.</summary>
1961

    
1962
        public XdmItem GlobalContextItem
1963
        {
1964
            set
1965
            {
1966
               transformer.setGlobalContextItem(value == null ? null : XdmItem.FromXdmItemItemToJXdmItem(value));
1967
            }
1968
            get { return (XdmItem)XdmItem.Wrap(transformer.getUnderlyingController().getGlobalContextItem()); }
1969

    
1970
        }
1971

    
1972

    
1973
		/// <summary> Get the underlying <c>Controller</c> used to implement this <c>XsltTransformer</c>. This provides access
1974
        /// to lower-level methods not otherwise available in the Saxon.Api interface. Note that classes
1975
        /// and methods obtained by this route cannot be guaranteed stable from release to release.</summary>
1976

    
1977
        public JXsltController GetUnderlyingController
1978
        {
1979
            get { return transformer.getUnderlyingController(); }
1980
        }
1981

    
1982
        internal JXslt30Transformer GetUnderlyingXslt30Transformer
1983
        {
1984
            get { return transformer; }
1985
        }
1986

    
1987

    
1988
        /// <summary>
1989
		/// Construct a <c>Destination</c> object whose effect is to perform this transformation
1990
		/// on any input that is sent to that <c>Destination</c>: for example, it allows this transformation
1991
		/// to post-process the results of another transformation.
1992
		/// </summary>
1993
		/// <remarks>
1994
        /// <para>This method allows a pipeline of transformations to be created in which
1995
        /// one transformation is used as the destination of another. The transformations
1996
        /// may use streaming, in which case intermediate results will not be materialized
1997
        /// in memory. If a transformation does not use streaming, then its input will
1998
        /// first be assembled in memory as a node tree.</para>
1999
		/// <para>The <c>Destination</c> returned by this method performs <em>sequence normalization</em>
2000
        /// as defined in the serialization specification: that is, the raw result of the transformation
2001
        /// sent to this destination is wrapped into a document node. Any item-separator present in
2002
        /// any serialization parameters is ignored (adjacent atomic values are separated by whitespace). 
2003
        /// This makes the method unsuitable for passing intermediate results other than XML document
2004
        /// nodes.</para>
2005
		/// </remarks>
2006
        /// <param name="finalDestination">supplied final destination</param>
2007
		/// <returns>a <c>Destination</c> which accepts an XML document (typically as a stream
2008
        /// of events) and which transforms this supplied XML document (possibly using streaming)
2009
		/// as defined by the stylesheet from which which this <c>Xslt30Transformer</c>
2010
        /// was generated,
2011
		/// sending the principal result of the transformation to the supplied <c>finalDestination</c>.
2012
		/// The transformation is performed as if by the <see cref="ApplyTemplates(Stream, XmlDestination)"/>
2013
        /// method: that is, by applying templates to the root node of the supplied XML document.
2014
		/// </returns>
2015
        public XmlDestination AsDocumentDestination(XmlDestination finalDestination) {
2016

    
2017
            AbstractDestination localDestination = new AbstractDestination(this, finalDestination);
2018
            return localDestination;
2019
        }
2020

    
2021
		// internal method
2022
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
2023
        {
2024
            JReceiver r = transformer.getDestinationReceiver(transformer.getUnderlyingController(), destination.GetUnderlyingDestination()); 
2025
            return r;
2026
        }
2027

    
2028

    
2029

    
2030
        /// <summary>
2031
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
2032
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
2033
        /// attribute.
2034
        /// </summary>
2035
        /// <remarks>
2036
        /// In the absence of a user-supplied result document handler, the <c>href</c>
2037
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
2038
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
2039
        /// and the resulting absolute URI must identify a writable resource (typically
2040
        /// a file in filestore, using the <c>file:</c> URI scheme).
2041
        /// </remarks>
2042

    
2043
        public IResultDocumentHandler ResultDocumentHandler
2044
        {
2045
            get
2046
            {
2047
                return resultDocumentHandler;
2048
            }
2049
            set
2050
            {
2051
                resultDocumentHandler = value;
2052
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
2053
            }
2054
        }
2055

    
2056
        /// <summary>
2057
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
2058
        /// loaded using the <code>doc()</code>, <code>document()</code>, or <code>collection()</code> functions.
2059
        /// </summary>
2060

    
2061
        public SchemaValidationMode SchemaValidationMode
2062
        {
2063
            get
2064
            {
2065
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
2066
                {
2067
                    case JValidation.STRICT:
2068
                        return SchemaValidationMode.Strict;
2069
                    case JValidation.LAX:
2070
                        return SchemaValidationMode.Lax;
2071
                    case JValidation.STRIP:
2072
                        return SchemaValidationMode.None;
2073
                    case JValidation.PRESERVE:
2074
                        return SchemaValidationMode.Preserve;
2075
                    case JValidation.DEFAULT:
2076
                    default:
2077
                        return SchemaValidationMode.Unspecified;
2078
                }
2079
            }
2080

    
2081

    
2082
            set
2083
            {
2084
                switch (value)
2085
                {
2086
                    case SchemaValidationMode.Strict:
2087
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
2088
                        break;
2089
                    case SchemaValidationMode.Lax:
2090
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
2091
                        break;
2092
                    case SchemaValidationMode.None:
2093
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
2094
                        break;
2095
                    case SchemaValidationMode.Preserve:
2096
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
2097
                        break;
2098
                    case SchemaValidationMode.Unspecified:
2099
                    default:
2100
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
2101
                        break;
2102
                }
2103
            }
2104
        }
2105

    
2106

    
2107

    
2108
        /// <summary> Supply the values of global stylesheet variables and parameters.</summary>
2109
		/// <param name="parameters"> A <c>Dictionary</c> whose keys are QNames identifying global stylesheet parameters,
2110
        /// and whose corresponding values are the values to be assigned to those parameters. If necessary
2111
        /// the supplied values are converted to the declared type of the parameter.
2112
		/// The contents of the supplied <c>Dictionary</c> are copied by this method,
2113
		/// so subsequent changes to the <c>Dictionary</c> have no effect.</param>
2114

    
2115
        public void SetStylesheetParameters(Dictionary<QName, XdmValue> parameters)
2116
        {
2117
            try
2118
            {
2119
                JMap map = new java.util.HashMap();
2120
                foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2121
                {
2122
                    QName qname = entry.Key;
2123
                    map.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2124
                }
2125
                transformer.setStylesheetParameters(map);
2126

    
2127
            }
2128
            catch (net.sf.saxon.trans.XPathException e)
2129
            {
2130
                throw new StaticError(e);
2131
            }
2132

    
2133
        }
2134

    
2135

    
2136

    
2137
        /// <summary>Get the base output URI.</summary>
2138
        /// <remarks><para> This returns the value set using the setter method. If no value has been set
2139
        /// explicitly, then the method returns null if called before the transformation, or the computed
2140
        /// default base output URI if called after the transformation.
2141
        /// </para>
2142
        /// <para> The base output URI is used for resolving relative URIs in the <code>href</code> attribute
2143
        /// of the <code>xsl:result-document</code> instruction.</para></remarks>
2144
        /// <returns> The base output URI</returns>
2145

    
2146
        public String BaseOutputURI
2147
        {
2148
            set
2149
            {
2150
                transformer.setBaseOutputURI(value);
2151
            }
2152
            get { return transformer.getBaseOutputURI(); }
2153
        }
2154

    
2155
        /// <summary>
2156
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
2157
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
2158
        /// </summary>
2159

    
2160
        public XmlResolver InputXmlResolver
2161
        {
2162
            get
2163
            {
2164
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
2165
            }
2166
            set
2167
            {
2168
                transformer.setURIResolver(new JDotNetURIResolver(value));
2169
            }
2170
        }
2171

    
2172
        /// <summary>
2173
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time. 
2174
        /// </summary>
2175
        /// <remarks>By default they are disabled at compile time. If assertions are enabled at compile time, then by
2176
        /// default they will also be enabled at run time; but they can be disabled at run time by
2177
        /// specific request. At compile time, assertions can be enabled for some packages and
2178
        /// disabled for others; at run time, they can only be enabled or disabled globally.</remarks>
2179
        /// <returns>true if assertions are enabled at run time</returns>
2180
        /// <remarks>Since 9.7</remarks>
2181
 
2182
        public bool AssertionsEnabled
2183
        {
2184
            get
2185
            {
2186
                return transformer.isAssertionsEnabled();
2187
            }
2188
        }
2189

    
2190

    
2191
        /// <summary>
2192
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time.
2193
        /// This property name has been misspelt, use <c>AssertionsEnabled</c> instead.
2194
        /// </summary>
2195
        [Obsolete("This property has been replaced by AssertionsEnabled.")]
2196
        public bool ssAssertionsEnabled
2197
        {
2198
            get
2199
            {
2200
                return transformer.isAssertionsEnabled();
2201
            }
2202
        }
2203

    
2204

    
2205
        /// <summary>
2206
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2207
		/// </summary>
2208
		/// <remarks> 
2209
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2210
        /// the processor will then invoke the listener once for each message generated during
2211
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2212
        /// representing a document node.</para>
2213
        /// <para>If no message listener is supplied by the caller, message information will be written to
2214
        /// the standard error stream.</para>
2215
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2216
        /// on the message object will usually generate an acceptable representation of the
2217
        /// message.</para>
2218
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2219
        /// the message is first notified using this interface, and then an exception is thrown
2220
        /// which terminates the transformation.</para>
2221
        /// </remarks>
2222

    
2223
        public IMessageListener MessageListener
2224
        {
2225
            set
2226
            {
2227
                messageListener = value;
2228
                transformer.setMessageListener(new MessageListenerProxy(value));
2229
            }
2230
            get
2231
            {
2232
                return messageListener;
2233
            }
2234
        }
2235

    
2236

    
2237

    
2238
        /// <summary>
2239
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2240
        /// </summary>
2241
        /// <remarks> 
2242
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2243
        /// the processor will then invoke the listener once for each message generated during
2244
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2245
        /// representing a document node.</para>
2246
        /// <para>If no message listener is supplied by the caller, message information will be written to
2247
        /// the standard error stream.</para>
2248
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2249
        /// on the message object will usually generate an acceptable representation of the
2250
        /// message.</para>
2251
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2252
        /// the message is first notified using this interface, and then an exception is thrown
2253
        /// which terminates the transformation.</para>
2254
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
2255
        /// in allowing the error code supplied to xsl:message to be notified</para>
2256
        /// </remarks>
2257

    
2258
        public IMessageListener2 MessageListener2
2259
        {
2260
            set
2261
            {
2262
                messageListener2 = value;
2263
                transformer.setMessageListener(new MessageListenerProxy2(value));
2264
            }
2265
            get
2266
            {
2267
                return messageListener2;
2268
            }
2269
        }
2270

    
2271
        /// <summary>
2272
        /// Destination for output of messages using the <c>trace()</c> function. 
2273
        /// </summary>
2274
		/// <remarks>
2275
		/// <para>If no message listener is supplied by the caller, message information will be written to
2276
		/// the standard error stream.</para>
2277
        /// <para>The supplied destination is ignored if a <code>TraceListener</code> is in use.</para>
2278
        /// </remarks>
2279

    
2280
        public StandardLogger TraceFunctionDestination
2281
        {
2282
            set
2283
            {
2284
                traceFunctionDestination = value;
2285
                transformer.setTraceFunctionDestination(value);
2286
            }
2287
            get
2288
            {
2289
                return traceFunctionDestination;
2290
            }
2291
        }
2292

    
2293

    
2294
        /// <summary>Set parameters to be passed to the initial template. These are used
2295
        /// whether the transformation is invoked by applying templates to an initial source item,
2296
        /// or by invoking a named template. The parameters in question are the <c>xsl:param</c> elements
2297
        /// appearing as children of the <c>xsl:template</c> element.
2298
		/// </summary>
2299
        /// <remarks>
2300
        /// <para>The parameters are supplied in the form of a map; the key is a <c>QName</c> which must
2301
        /// match the name of the parameter; the associated value is an <c>XdmValue</c> containing the
2302
        /// value to be used for the parameter. If the initial template defines any required
2303
        /// parameters, the map must include a corresponding value. If the initial template defines
2304
        /// any parameters that are not present in the map, the default value is used. If the map
2305
        /// contains any parameters that are not defined in the initial template, these values
2306
        /// are silently ignored.</para>
2307
        /// <para>The supplied values are converted to the required type using the function conversion
2308
        /// rules. If conversion is not possible, a run-time error occurs (not now, but later, when
2309
        /// the transformation is actually run).</para>
2310
        /// <para>The <code>Xslt30Transformer</code> retains a reference to the supplied map, so parameters can be added or
2311
        /// changed until the point where the transformation is run.</para>
2312
        /// <para>The XSLT 3.0 specification makes provision for supplying parameters to the initial
2313
        /// template, as well as global stylesheet parameters. Although there is no similar provision
2314
        /// in the XSLT 1.0 or 2.0 specifications, this method works for all stylesheets, regardless whether
2315
        /// XSLT 3.0 is enabled or not.</para></remarks>
2316

    
2317
        /// <param name="parameters"> The parameters to be used for the initial template</param>
2318
        /// <param name="tunnel"> true if these values are to be used for setting tunnel parameters;
2319
        /// false if they are to be used for non-tunnel parameters</param>
2320

    
2321
        public void SetInitialTemplateParameters(Dictionary<QName, XdmValue> parameters, bool tunnel)
2322
        {
2323

    
2324
            JMap templateParameters = new java.util.HashMap();
2325
            foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2326
            {
2327
                QName qname = entry.Key;
2328
                templateParameters.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2329
            }
2330

    
2331
            transformer.setInitialTemplateParameters(templateParameters, tunnel);
2332

    
2333

    
2334
        }
2335

    
2336

    
2337
        /// <summary>Initial mode for the transformation. This is used if the stylesheet is
2338
        /// subsequently invoked by any of the <code>applyTemplates</code> methods.</summary>
2339
        /// <remarks><para>The value may be the name of the initial mode, or null to indicate the default
2340
        /// (unnamed) mode</para></remarks>
2341

    
2342
        public QName InitialMode
2343
        {
2344

    
2345
            set
2346
            {
2347
                try
2348
                {
2349
                    transformer.setInitialMode(value == null ? null : value.UnderlyingQName());
2350
                }
2351
                catch (net.sf.saxon.trans.XPathException e)
2352
                {
2353
                    throw new DynamicError(e);
2354
                }
2355
            }
2356
            get
2357
            {
2358
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
2359
                if (mode == null)
2360
                    return null;
2361
                else
2362
                {
2363
                    return new QName(mode);
2364
                }
2365
            }
2366

    
2367

    
2368
        }
2369

    
2370

    
2371
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2372
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2373
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2374
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2375
        /// </summary>
2376
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2377
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2378
        /// <param name="destination">The destination of the result document produced by wrapping the result 
2379
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2380
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2381
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2382

    
2383
        public void ApplyTemplates(Stream input, XmlDestination destination)
2384
        {
2385
            try
2386
            {
2387
                JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2388
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2389
            
2390
            }
2391
            catch (JSaxonApiException exp)
2392
            {
2393
                throw new DynamicError(exp);
2394
            }
2395

    
2396
        }
2397

    
2398

    
2399
		/// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2400
		/// using the supplied base URI,
2401
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2402
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2403
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2404
		/// </summary>
2405
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2406
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2407
		/// <param name="baseUri">Base URI used for the input document</param>
2408
		/// <param name="destination">The destination of the result document produced by wrapping the result 
2409
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2410
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2411
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2412

    
2413
        public void ApplyTemplates(Stream input, Uri baseUri, XmlDestination destination)
2414
        {
2415
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2416
            try
2417
            {
2418
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2419
            }
2420
            catch (JSaxonApiException exp)
2421
            {
2422
                throw new DynamicError(exp.getMessage());
2423
            }
2424

    
2425
        }
2426

    
2427

    
2428
        /// <summary>
2429
        /// Invoke the stylesheet by applying templates to a supplied source document, sending the results
2430
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2431
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2432
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2433
        /// </summary>
2434
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2435
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2436
        /// <param name="destination">The destination of the principal result of the transformation.
2437
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2438
        /// parameters set in the serializer are combined with those defined in the stylesheet
2439
        /// (the parameters set in the serializer take precedence).</param>
2440
        /// <remarks>since 9.9.1.5</remarks>
2441
        public void Transform(Stream input, XmlDestination destination) {
2442
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2443

    
2444
            try
2445
            {
2446
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2447
            }
2448
            catch (JSaxonApiException exp)
2449
            {
2450
                throw new DynamicError(exp.getMessage());
2451
            }
2452

    
2453
        }
2454

    
2455
        /// <summary>
2456
        /// Invoke the stylesheet by applying templates to a supplied Source document,  
2457
        /// using the supplied base URI, sending the results
2458
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2459
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2460
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2461
        /// </summary>
2462
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2463
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2464
        /// <param name="baseUri">Base URI used for the input document</param>
2465
        /// <param name="destination">The destination of the principal result of the transformation.
2466
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2467
        /// parameters set in the serializer are combined with those defined in the stylesheet
2468
        /// (the parameters set in the serializer take precedence).</param>
2469
        /// <remarks>since 9.9.1.5</remarks>
2470
        public void Transform(Stream input, Uri baseUri, XmlDestination destination)
2471
        {
2472
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2473
            try
2474
            {
2475
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2476
            }
2477
            catch (JSaxonApiException exp)
2478
            {
2479
                throw new DynamicError(exp.getMessage());
2480
            }
2481

    
2482
        }
2483

    
2484

    
2485

    
2486

    
2487
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2488
		/// using the supplied base URI,
2489
		/// returning the raw results as an <c>XdmValue</c>. The 
2490
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2491
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2492
		/// </summary>
2493
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2494
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2495
		/// <param name="baseUri">Base URI</param>
2496
		/// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2497
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2498
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2499

    
2500
        public XdmValue ApplyTemplates(Stream input, Uri baseUri)
2501
        {
2502
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2503

    
2504
            try
2505
            {
2506
                net.sf.saxon.s9api.XdmValue value = transformer.applyTemplates(streamSource);
2507
                return XdmValue.Wrap(value.getUnderlyingValue());
2508

    
2509
            }
2510
            catch (JSaxonApiException exp)
2511
            {
2512
                throw new DynamicError(exp);
2513
            }
2514

    
2515
        }
2516

    
2517

    
2518
        /// <summary>
2519
        /// Invoke the stylesheet by applying templates to a supplied input sequence, sending the results (wrapped
2520
		/// in a document node) to a given <c>Destination</c>. The invocation uses any initial mode set using 
2521
		/// <see cref="InitialMode"/>, and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2522
        /// </summary>
2523
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2524
        /// attribute of <code>xsl:apply-templates</code>)</param>
2525
        /// <param name="destination">The destination of the result document produced by wrapping the result of the apply-templates
2526
        /// call in a document node.  If the destination is a <see cref="Serializer"/>, then the serialization
2527
        /// parameters set in the serializer are combined with those defined in the stylesheet
2528
        /// (the parameters set in the serializer take precedence).</param>
2529

    
2530
        public void ApplyTemplates(XdmValue selection, XmlDestination destination)
2531
        {
2532
            
2533
            try
2534
            {
2535
                transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value), destination.GetUnderlyingDestination());
2536
            }
2537
            catch (JSaxonApiException ex)
2538
            {
2539

    
2540
                throw new DynamicError(ex);
2541
            }
2542

    
2543
        }
2544

    
2545

    
2546

    
2547
        /// <summary>
2548
        /// Invoke the stylesheet by applying templates to a supplied input sequence, returning the raw results
2549
        /// as an <see cref="XdmValue"/>. The invocation uses any initial mode set using <see cref="InitialMode"/>,
2550
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2551
        /// </summary>
2552
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2553
        /// attribute of <code>xsl:apply-templates</code>)</param>
2554
        /// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2555
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2556
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2557

    
2558
        public XdmValue ApplyTemplates(XdmValue selection)
2559
        {
2560
           
2561
            try
2562
            {
2563
                return XdmValue.Wrap(transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value)).getUnderlyingValue());
2564
               
2565
            }
2566
            catch (JSaxonApiException ex)
2567
            {
2568

    
2569
                throw new DynamicError(ex);
2570
            }
2571

    
2572
        }
2573

    
2574

    
2575
        /// <summary> Invoke a transformation by calling a named template. The results of calling
2576
        /// the template are wrapped in a document node, which is then sent to the specified
2577
        /// destination. If <see cref="SetInitialTemplateParameters"/> has been
2578
        /// called, then the parameters supplied are made available to the called template (no error
2579
        /// occurs if parameters are supplied that are not used).</summary> 
2580
        /// <param name="templateName"> The name of the initial template. This must match the name of a
2581
        /// public named template in the stylesheet. If the value is null,
2582
        /// the QName <code>xsl:initial-template</code> is used.</param>
2583
        /// <param name="destination"> The destination of the result document produced by wrapping the result 
2584
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2585
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2586
        /// (the parameters set in the serializer take precedence).</param> 
2587

    
2588
        public void CallTemplate(QName templateName, XmlDestination destination)
2589
        {
2590
           
2591
            if (templateName == null)
2592
            {
2593
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2594
            }
2595

    
2596
            try
2597
            {
2598
                transformer.callTemplate(templateName.UnderlyingQName(), destination.GetUnderlyingDestination());
2599
               
2600
            }
2601
            catch (JSaxonApiException exp)
2602
            {
2603
                throw new DynamicError(exp);
2604
            }
2605
        }
2606

    
2607

    
2608

    
2609
        /// <summary>
2610
        /// Invoke a transformation by calling a named template. The results of calling
2611
        /// the template are returned as a raw value, without wrapping in a document nnode
2612
        /// or serializing.
2613
        /// </summary>
2614
        /// <param name="templateName">The name of the initial template. This must match the name of a
2615
        /// public named template in the stylesheet. If the value is null, the QName <c>xsl:initial-template</c> is used.</param>
2616
        /// <returns>the raw results of the called template, without wrapping in a document node or serialization.</returns>
2617

    
2618
        public XdmValue CallTemplate(QName templateName)
2619
        {
2620
            if (templateName == null)
2621
            {
2622
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2623
            }
2624

    
2625
            try
2626
            {
2627
                return XdmValue.Wrap(transformer.callTemplate(templateName.UnderlyingQName()).getUnderlyingValue());
2628
            }
2629
            catch (JSaxonApiException exp)
2630
            {
2631
                throw new DynamicError(exp);
2632
            }
2633
        }
2634

    
2635

    
2636
        /// <summary> Call a public user-defined function in the stylesheet. </summary>
2637
        /// <param name="function"> The name of the function to be called</param>
2638
        /// <param name="arguments">  The values of the arguments to be supplied to the function. These
2639
        /// will be converted if necessary to the type as defined in the function signature, using
2640
        /// the function conversion rules.</param>
2641
        /// <returns> the result of calling the function. This is the raw result, without wrapping in a document
2642
        /// node and without serialization.</returns>
2643

    
2644
        public XdmValue CallFunction(QName function, XdmValue[] arguments)
2645
        {
2646
            try
2647
            {
2648
                int len = arguments.Length;
2649
                net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2650

    
2651
                for (int i=0; i<len; i++) {
2652
                    values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2653

    
2654
                }
2655

    
2656
                return XdmValue.Wrap(transformer.callFunction(function.UnderlyingQName(), values).getUnderlyingValue());
2657

    
2658
            }
2659
            catch (JSaxonApiException ex)
2660
            {
2661
                throw new DynamicError(ex);
2662

    
2663
            }
2664

    
2665
        }
2666

    
2667

    
2668

    
2669
        /// <summary>Call a public user-defined function in the stylesheet, wrapping the result in an XML document, 
2670
		/// and sending this document to a specified destination</summary>    
2671
        /// <param name="function"> The name of the function to be called</param>
2672
        /// <param name="arguments"> The values of the arguments to be supplied to the function. These
2673
        /// will be converted if necessary to the type as defined in the function signature, using
2674
        /// the function conversion rules.</param>
2675
        /// <param name="destination"> The destination of the result document produced by wrapping the 
2676
		/// result of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2677
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2678
        /// (the parameters set in the serializer take precedence).</param>
2679

    
2680
        public void CallFunction(QName function, XdmValue[] arguments, XmlDestination destination)
2681
        {
2682

    
2683
            int len = arguments.Length;
2684
            net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2685

    
2686
            for (int i = 0; i < len; i++)
2687
            {
2688
                values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2689

    
2690
            }
2691
            try
2692
            {
2693
                transformer.callFunction(function.UnderlyingQName(), values, destination.GetUnderlyingDestination());
2694

    
2695
            }
2696
            catch (JSaxonApiException ex) {
2697
                throw new DynamicError(ex);
2698
            }
2699
        }
2700

    
2701
        internal class AbstractDestination : XmlDestination
2702
        {
2703
            private Xslt30Transformer xslt30Transformer;
2704
            private XmlDestination destination;
2705

    
2706
			internal AbstractDestination(Xslt30Transformer xslt30Transformer, XmlDestination destination)
2707
            {
2708
                this.xslt30Transformer = xslt30Transformer;
2709
                this.destination = destination;
2710
            }
2711

    
2712
			JDestination XmlDestination.GetUnderlyingDestination()
2713
            {
2714
                return xslt30Transformer.GetUnderlyingXslt30Transformer.asDocumentDestination(destination.GetUnderlyingDestination());
2715
            }
2716
        }
2717
    }
2718

    
2719
    /// <summary> An <c>XsltPackage</c> object represents the result of compiling an XSLT 3.0 package, as
2720
    /// represented by an XML document containing an <c>xsl:package</c> element.</summary>
2721

    
2722
    [Serializable]
2723
    public class XsltPackage
2724
    {
2725
        private JXsltPackage package;
2726
        private Processor processor;
2727
		// internal constructor: Initializes a new instance of the <see cref="Saxon.Api.XsltPackage"/> class.
2728
        internal XsltPackage(Processor p, JXsltPackage pp)
2729
        {
2730
            this.package = pp;
2731
            this.processor = p;
2732

    
2733
        }
2734

    
2735
        /// <summary>
2736
        /// Get the Processor from which this <c>XsltPackage</c> was constructed
2737
        /// </summary>
2738

    
2739
        public Processor Processor
2740
        {
2741
            get { return processor; }
2742
        }
2743

    
2744

    
2745
        /// <summary>
2746
        /// Get the name of the package (the URI appearing as the value of <code>xsl:package/@name</code>)
2747
        /// </summary>
2748
        /// <returns>The package name</returns>
2749

    
2750
        public String PackageName
2751
        {
2752
            get { return package.getName(); }
2753
        }
2754

    
2755

    
2756
        /// <summary>Get the version number of the package (the value of the attribute 
2757
		/// <code>xsl:package/@package-version</code></summary>
2758
        /// <returns>The package version number</returns>
2759

    
2760
        public String Version
2761
        {
2762
            get { return package.getVersion(); }
2763
        }
2764

    
2765

    
2766
        /// <summary>Link this package with the packages it uses to form an executable stylesheet. This process fixes
2767
        /// up any cross-package references to files, templates, and other components, and checks to ensure
2768
        /// that all such references are consistent.</summary>
2769
		/// <returns> the resulting <c>XsltExecutable</c></returns>
2770

    
2771
        public XsltExecutable Link()
2772
        {
2773
            try
2774
            {
2775
                JXsltExecutable executable = package.link();
2776
                return new XsltExecutable(executable);
2777
            }
2778
            catch (net.sf.saxon.trans.XPathException e)
2779
            {
2780
                throw new StaticError(e);
2781
            }
2782
        }
2783

    
2784
        /// <summary>Save this compiled package to filestore.</summary>
2785
        /// <param name="stream"> the stream to which the compiled package should be saved</param>
2786

    
2787
        public void Save(Stream stream)
2788
        {
2789
            JDotNetOutputStream outputStream = new JDotNetOutputStream(stream);
2790
            JExpressionPresenter outp = new JExpressionPresenter(package.getProcessor().getUnderlyingConfiguration(), new javax.xml.transform.stream.StreamResult(outputStream), true);
2791
            try
2792
            {
2793
                package.getUnderlyingPreparedPackage().export(outp);
2794
            }
2795
            catch (net.sf.saxon.trans.XPathException e)
2796
            {
2797
                throw new StaticError(e);
2798
            }
2799
        }
2800

    
2801

    
2802
        /// <summary>Escape-hatch interface to the underlying implementation class.</summary>
2803
		/// <returns>the underlying <c>StylesheetPackage</c>. The interface to <c>StylesheetPackage</c>
2804
        /// is not a stable part of the s9api API definition.</returns>
2805

    
2806
        public JStylesheetPackage getUnderlyingPreparedPackage()
2807
        {
2808
            return package.getUnderlyingPreparedPackage();
2809
        }
2810

    
2811
    }
2812

    
2813

    
2814
}
2815

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