Project

Profile

Help

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

he / src / main / csharp / api / Saxon.Api / Xslt.cs @ c7deb2a9

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 JDotNetOutputStream = net.sf.saxon.dotnet.DotNetOutputStream;
48
using JDestination = net.sf.saxon.s9api.Destination;
49
using javax.xml.transform;
50
using JResultDocumentResolver = net.sf.saxon.lib.ResultDocumentResolver;
51
using System.Runtime.CompilerServices;
52

    
53
namespace Saxon.Api
54
{
55

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

    
71
    [Serializable]
72
    public class XsltCompiler
73
    {
74
        private Processor processor;
75
        private Uri baseUri;
76
        private ErrorReporterToStaticError errorGatherer;
77
        private ErrorReporter errorReporter;
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 ErrorReporterToStaticError(new List<StaticError>());
90
            errorReporter = new ErrorReporter(new List<XmlProcessingError>());
91
            //xsltCompiler.setErrorReporter(errorReporter);
92
            xsltCompiler.setURIResolver(processor.Implementation.getURIResolver());
93
        }
94

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

    
110

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

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

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

    
139
        /// <summary>
140
        /// The name of the default collation used by stylesheets compiled using this <c>XsltCompiler</c>.
141
        /// This must be the name of a collation that is known to the <c>Processor</c>.
142
        /// </summary>
143

    
144
        public String DefaultCollationName
145
        {
146
            get { return xsltCompiler.getDefaultCollation(); }
147
            set { xsltCompiler.declareDefaultCollation(value); }
148
        }
149

    
150
        /// <summary>
151
        /// The <c>Processor</c> from which this <c>XsltCompiler</c> was constructed
152
        /// </summary>
153

    
154
        public Processor Processor
155
        {
156
            get { return processor; }
157
        }
158

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

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

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

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

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

    
224

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

    
234

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

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

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

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

    
281
        public bool ByteCodeEnabled {
282

    
283
            get { return xsltCompiler.getUnderlyingCompilerInfo().isGenerateByteCode(); }
284
            set { xsltCompiler.getUnderlyingCompilerInfo().setGenerateByteCode(value); }
285
        }
286

    
287

    
288

    
289
        /// <summary>
290
        /// Property to say whether just-in-time compilation of template rules should be used.
291
        /// jit true if just-in-time compilation is to be enabled. With this option enabled,
292
        /// static analysis of a template rule is deferred until the first time that the
293
        /// template is matched.This can improve performance when many template
294
        /// rules are rarely used during the course of a particular transformation; however,
295
        /// it means that static errors in the stylesheet will not necessarily cause the
296
        /// <code>Compile(Source)</code> method to throw an exception (errors in code that is
297
        ///  actually executed will still be notified to the registered <code>ErrorList</code>
298
        ///  or <code>ErrorList</code>, but this may happen after the {
299
        /// <c>Compile(Source)</c>
300
        ///  method returns). This option is enabled by default in Saxon - EE, and is not available
301
        ///  in Saxon - HE or Saxon-PE.
302
        ///  <p><b> Recommendation:</b> disable this option unless you are confident that the
303
        ///  stylesheet you are compiling is error - free.</p>
304
        /// </summary>
305
        public bool JustInTimeCompilation {
306
            get { return xsltCompiler.isJustInTimeCompilation(); }
307
            set { xsltCompiler.setJustInTimeCompilation(value); }
308
        }
309

    
310

    
311

    
312
        /// <summary>
313
        /// List of errors. The caller should supply an empty list before calling Compile;
314
        /// the processor will then populate the list with error information obtained during
315
        /// the compilation. Each error will be included as an object of type <c>StaticError</c>.
316
        /// If no error list is supplied by the caller, error information will be written to
317
        /// an error list allocated by the system, which can be obtained as the value of this property.
318
        /// </summary>
319
        /// <remarks>
320
		/// By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
321
        /// intercept error conditions as they occur.
322
        /// </remarks>
323
        [Obsolete("IList<StaticError> ErrorList is deprecated, please use the methods SetErrorList and GetErrorList which hanldes IList<XmlProcessingError>.")]
324
        public IList<StaticError> ErrorList
325
        {
326
            set
327
            {
328
                errorGatherer = new ErrorReporterToStaticError(value);
329
                xsltCompiler.setErrorReporter(errorGatherer);
330
            }
331
            get
332
            {
333
                return errorGatherer.ErrorList;
334
            }
335
        }
336

    
337
        /// <summary>Set the <c>ErrorReporter</c> to be used when validating instance documents as a user defined IErrorReporter.
338
        /// If this property is used then the ErrorList property and SetErrorList method is overriden </summary>
339
        /// <remarks>The <c>IErrorReporter</c> to be used</remarks>
340
        public IErrorReporter ErrorReporter
341
        {
342
            set
343
            {
344
                errorReporter = null;
345
                xsltCompiler.setErrorReporter(new ErrorReporterWrapper(value));
346
            }
347

    
348
        }
349

    
350

    
351
        /// <summary>
352
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
353
        /// the processor will then populate the list with error information obtained during
354
		/// the XSLT compilation. Each error will be included as an object of type <c>XmlProcessingError</c>.
355
        /// If no error list is supplied by the caller, error information will be written to
356
        /// the standard error stream.
357
        /// </summary>
358
        /// <remarks>
359
		/// <para>By supplying a custom <c>List</c> or IErrorReport implementation with a user-written <c>report()</c> method, it is possible to
360
        /// intercept error conditions as they occur.</para>
361
        /// <para>Note that this error list is used only for errors detected during the compilation
362
        /// of the stylesheet. It is not used for errors detected when executing the stylesheet.</para>
363
		/// </remarks>
364
		/// <param name="value">Supplied list.</param>
365
        public void SetErrorList(IList<XmlProcessingError> value)
366
        {
367
            errorReporter = new ErrorReporter(value);
368
            xsltCompiler.setErrorReporter(errorReporter);
369
        }
370

    
371
		/// <summary>
372
		/// Get list of errors as <code>IList&lt;XmlProcessingError&gt;</code>
373
		/// </summary>
374
        public IList<XmlProcessingError> GetErrorList()
375
        {
376
            return errorReporter.ErrorList;
377

    
378
        }
379

    
380

    
381

    
382
        /// <summary>
383
        /// Compile a stylesheet supplied as a Stream.
384
        /// </summary>
385
        /// <example>
386
        /// <code>
387
        /// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
388
        /// XsltExecutable q = compiler.Compile(source);
389
        /// source.Close();
390
        /// </code>
391
        /// </example>
392
        /// <param name="input">A stream containing the source text of the stylesheet</param>
393
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
394
        /// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
395
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
396
        /// once it has been compiled.</returns>
397
        /// <remarks>
398
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
399
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
400
        /// <para>The stylesheet is contained in the part of the input stream between its current
401
        /// position and the end of the stream. It is the caller's responsibility to close the input 
402
        /// stream after use. If the compilation succeeded, then on exit the stream will be 
403
        /// exhausted; if compilation failed, the current position of the stream on exit is
404
        /// undefined.</para>
405
        /// </remarks>
406

    
407
        public XsltExecutable Compile(Stream input)
408
        {
409
            try
410
            {
411
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
412
                if (baseUri != null)
413
                {
414
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
415
                }
416
                XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(ss));
417
                executable.InternalProcessor = processor;
418
                return executable;
419
            }
420
            catch (JSaxonApiException err)
421
            {
422
                throw new StaticError(err);
423
            }
424
        }
425

    
426
		// internal method: Compile a stylesheet supplied as a Stream.
427
		// For example:
428
		// <code>
429
		// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
430
		// XsltExecutable q = compiler.Compile(source);
431
		// source.Close();
432
		// </code>
433
		// <param name="input">A stream containing the source text of the stylesheet</param>
434
		// <param name="theBaseUri">Specify the base URI of the stream</param>
435
		// <param name="closeStream">Flag to indicate if the stream should be closed in the method</param>
436
		// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
437
		// The XsltExecutable may be loaded as many times as required, in the same or a different
438
		// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
439
		// once it has been compiled.</returns>
440
		// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
441
		// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
442
		// <para>The stylesheet is contained in the part of the input stream between its current
443
		// position and the end of the stream. It is the caller's responsibility to close the input 
444
		// stream after use. If the compilation succeeded, then on exit the stream will be 
445
		// exhausted; if compilation failed, the current position of the stream on exit is
446
		// undefined.</para>
447

    
448
        internal XsltExecutable Compile(Stream input, String theBaseUri, bool closeStream)
449
        {
450
            //See bug 2306
451
            try
452
            {
453
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
454
                if (theBaseUri != null)
455
                {
456
                    ss.setSystemId(Uri.EscapeUriString(theBaseUri.ToString()));
457
                }
458
                else
459
                {
460
                    if (baseUri != null)
461
                    {
462
                        ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
463
                    }
464
                }
465
                JXsltExecutable jexecutable =  xsltCompiler.compile(ss);
466
               
467
                if (closeStream)
468
                {
469
                    input.Close();
470
                }
471
                XsltExecutable executable = new XsltExecutable(jexecutable);
472
                executable.InternalProcessor = processor;
473
                return executable;
474
            }
475
            catch (JSaxonApiException err)
476
            {
477
                throw new StaticError(err);
478
            }
479
        }
480

    
481

    
482

    
483
        /// <summary>Compile a library package.</summary>
484
        /// <remarks>
485
        /// <para>The source argument identifies an XML file containing an <c>xsl:package</c> element. Any packages
486
        /// on which this package depends must have been made available to the <c>XsltCompiler</c>
487
        /// by importing them using <see cref="ImportPackage"/>.</para>
488
        /// </remarks>
489
        /// <param name='input'>source identifies an XML document holding the the XSLT package to be compiled</param>
490
        /// <returns>The <c>XsltPackage</c> that results from the compilation. Note that this package
491
        /// is not automatically imported to this <c>XsltCompiler</c>; if the package is required
492
        /// for use in subsequent compilations then it must be explicitly imported.</returns>
493

    
494
        public XsltPackage CompilePackage(Stream input)
495
        {
496
            try
497
            {
498
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
499
                if (baseUri != null)
500
                {
501
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
502
                }
503

    
504
                return new XsltPackage(processor, xsltCompiler.compilePackage(ss));
505
            }
506
            catch (JSaxonApiException err)
507
            {
508
                throw new StaticError(err);
509
            }
510
        }
511

    
512

    
513

    
514

    
515
        /// <summary>Compile a list of packages.</summary>
516
        /// <param name='sources'> the collection of packages to be compiled, in the form of an
517
		/// <c>Iterable</c></param>
518
		/// <returns> the collection of compiled packages, in the form of an <c>Iterable</c></returns> 
519
        [Obsolete("CompilePackages is deprecated, please use configuration to add list of packages.")]
520
        public IList<XsltPackage> CompilePackages(IList<String> sources)
521
        {
522
            JCompilerInfo compilerInfo = xsltCompiler.getUnderlyingCompilerInfo();
523
            JConfiguration config = xsltCompiler.getUnderlyingCompilerInfo().getConfiguration();
524
            JCompilation compilation = new JCompilation(config,compilerInfo);
525
            
526
             java.util.Set sourcesJList = new java.util.HashSet();
527

    
528
            foreach (String sourceStr in sources)
529
            {
530
                sourcesJList.add(new java.io.File(sourceStr));
531

    
532
            }
533

    
534

    
535
            java.lang.Iterable resultJList = null;
536

    
537
            try
538
            {
539
                compilerInfo.setPackageLibrary(new JPackageLibrary(compilerInfo, sourcesJList));
540

    
541
                resultJList =compilerInfo.getPackageLibrary().getPackages();
542

    
543

    
544
            }
545
            catch (JTransformerException ex)
546
            {
547
                throw new StaticError(ex);
548
            }
549
            IList<XsltPackage> result = new List<XsltPackage>();
550
            java.util.Iterator iter = resultJList.iterator();
551

    
552
            for (; iter.hasNext();)
553
            {
554
                JXsltPackage pp = (JXsltPackage)iter.next();
555
                result.Add(new XsltPackage(processor, pp));
556
            }
557

    
558
            return result;
559
        }
560

    
561

    
562

    
563

    
564
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
565
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
566
        /// <code>XsltCompiler</code>.</summary>
567
        /// <param name='thePackage'> the package to be imported</param>
568
        /// <remarks>since 9.6</remarks>
569

    
570
        public void ImportPackage(XsltPackage thePackage)
571
        {
572
            if (thePackage.Processor != this.processor)
573
            {
574
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
575
            }
576
            GetUnderlyingCompilerInfo().getPackageLibrary().addPackage(thePackage.getUnderlyingPreparedPackage());
577
        }
578

    
579

    
580
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
581
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
582
        /// <code>XsltCompiler</code>.</summary>
583
		/// <param name='thePackage'> the package to be imported</param>
584
		/// <param name='packageName'> name of the package to be imported</param>
585
		/// <param name='version'> version identifier for the package to be imported</param>
586
        /// <remarks>since 9.8</remarks>
587

    
588
        public void ImportPackage(XsltPackage thePackage, string packageName, string version)
589
        {
590
            if (thePackage.Processor != this.processor)
591
            {
592
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
593
            }
594
            try {
595
                JPackageDetails details = new JPackageDetails();
596
                if (packageName == null) {
597
                    packageName = thePackage.PackageName;
598
                }
599
                if (version == null) {
600
                    version = thePackage.Version;
601
                }
602
                details.nameAndVersion = new JVersionedPackageName(packageName, version);
603
                details.loadedPackage = thePackage.getUnderlyingPreparedPackage();
604
                xsltCompiler.getUnderlyingCompilerInfo().getPackageLibrary().addPackage(details);
605
            } catch (JTransformerException ex) {
606
                throw new StaticError(ex);
607
            }
608
        }
609

    
610

    
611
        /// <summary>
612
		/// Load a compiled package from a file or from a remote location.
613
		/// </summary>
614
		/// <remarks>
615
        /// The supplied URI represents the location of a resource which must have been originally
616
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
617
        /// The result of loading the package is returned as an <code>XsltPackage</code> object.
618
        /// Note that this package is not automatically imported to this <code>XsltCompiler</code>;
619
        /// if the package is required for use in subsequent compilations then it must be explicitly
620
        /// imported.
621
		/// </remarks>
622
        /// <param name="location">the location from which the package is to be loaded, as a URI</param>
623
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
624

    
625
        public XsltPackage LoadLibraryPackage(Uri location)
626
        {
627
            try
628
            {
629
                JXsltPackage package = xsltCompiler.loadLibraryPackage(new java.net.URI(location.ToString()));
630
                return new XsltPackage(processor, package);
631

    
632
            }
633
            catch (net.sf.saxon.trans.XPathException e)
634
            {
635
                throw new StaticError(e);
636
            }
637

    
638

    
639
        }
640

    
641
        /// <summary>
642
        /// Load a compiled package from a file or from a remote location, with the intent to use this as a complete
643
		/// executable stylesheet, not as a library package.
644
		/// </summary>
645
		/// <remarks>
646
        /// The supplied URI represents the location of a resource which must have been originally
647
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
648
		/// </remarks>
649
        /// <param name="location"> the location from which the package is to be loaded, as a URI</param>
650
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
651

    
652
        public XsltExecutable LoadExecutablePackage(Uri location)
653
        {
654
            XsltExecutable executable = LoadLibraryPackage(location).Link();
655
            executable.InternalProcessor = processor;
656
            return executable;
657
        }
658

    
659

    
660
        ///	<summary>  
661
		/// Get the underlying <c>CompilerInfo</c> object, which provides more detailed (but less stable) control
662
        /// over some compilation options
663
        /// </summary>
664
		/// <returns> the underlying <c>CompilerInfo</c> object, which holds compilation-time options. The methods on
665
        /// this object are not guaranteed stable from release to release.
666
        /// </returns>
667

    
668
        public JCompilerInfo GetUnderlyingCompilerInfo()
669
        {
670
            return xsltCompiler.getUnderlyingCompilerInfo();
671
        }
672

    
673

    
674

    
675
        /// <summary>
676
        /// Escape hatch to the underlying Java implementation of the <c>XsltCompiler</c>
677
        /// </summary>
678

    
679
        public JXsltCompiler Implementation
680
        {
681
            get { return xsltCompiler; }
682
        }
683

    
684

    
685
        /// <summary>
686
        /// Externally set the value of a static parameter (new facility in XSLT 3.0) 
687
        /// </summary>
688
        /// <param name="name">The name of the parameter, expressed
689
        /// as a QName. If a parameter of this name has been declared in the
690
        /// stylesheet, the given value will be assigned to the variable. If the
691
        /// variable has not been declared, calling this method has no effect (it is
692
        /// not an error).</param>
693
        /// <param name="value">The value to be given to the parameter.
694
        /// If the parameter declaration defines a required type for the variable, then
695
        /// this value will be converted in the same way as arguments to function calls
696
        /// (for example, numeric promotion is applied).</param>
697

    
698
        public void SetParameter(QName name, XdmValue value)
699
        {
700
            if (value == null)
701
            {
702
                if (variableList.ContainsKey(name))
703
                {
704
                    variableList.Remove(name);
705
                    xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), null);
706
                }
707
            }
708
            else
709
            {
710
                variableList[name] = value;
711
                xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), value.value);
712
            }
713
        }
714

    
715

    
716
        /// <summary>
717
        /// Clear the values of all stylesheet parameters previously set using <c>SetParameter(QName, XdmValue)</c>.
718
        /// This resets the parameters to their initial ("undeclared") state
719
        /// </summary>
720
        public void ClearParameters() {
721
            xsltCompiler.clearParameters();
722
        }
723

    
724
        /// <summary>
725
        /// Property to check and set fast compilation. Fast compilation will generally be achieved at the expense of run-time performance
726
        /// and quality of diagnostics. Fast compilation is a good trade-off if (a) the stylesheet is known to be correct,
727
        /// and (b) once compiled, it is only executed once against a document of modest size.
728
		/// </summary>
729
		/// <remarks>
730
        /// <para>Fast compilation may result in static errors going unreported, especially if they occur in code
731
        /// that is never executed.</para>
732
        /// <para><i>The current implementation is equivalent to switching off all optimizations other than just-in-time
733
        /// compilation of template rules. Setting this option, however, indicates an intent rather than a mechanism,
734
        /// and the implementation details may change in future to reflect the intent.</i></para>
735
        /// <para>Set to true to request fast compilation; set to false to revert to the optimization options
736
		/// defined in the Configuration.</para>
737
		/// </remarks>
738

    
739
        public bool FastCompilation {
740

    
741
            set { xsltCompiler.setFastCompilation(value); }
742
            get { return xsltCompiler.isFastCompilation(); }
743
        }
744

    
745

    
746
        [Obsolete("This property has been replaced by FastCompilation.")]
747
        public bool FastCompliation
748
        {
749

    
750
            set { xsltCompiler.setFastCompilation(value); }
751
            get { return xsltCompiler.isFastCompilation(); }
752
        }
753

    
754
        /// <summary>
755
		/// Compile a stylesheet supplied as a <c>TextReader</c>.
756
        /// </summary>
757
        /// <example>
758
        /// <code>
759
        /// String ss = "<![CDATA[<xsl:stylesheet version='2.0'>....</xsl:stylesheet>]]>";
760
        /// TextReader source = new StringReader(ss);
761
        /// XsltExecutable q = compiler.Compile(source);
762
        /// source.Close();
763
        /// </code>
764
        /// </example>
765
        /// <param name="input">A <c>TextReader</c> containing the source text of the stylesheet</param>
766
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
767
		/// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
768
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
769
        /// once it has been compiled.</returns>
770
        /// <remarks>
771
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
772
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
773
        /// <para>The stylesheet is contained in the part of the input stream between its current
774
        /// position and the end of the stream. It is the caller's responsibility to close the 
775
        /// <c>TextReader</c> after use. If the compilation succeeded, then on exit the stream will be 
776
        /// exhausted; if compilation failed, the current position of the stream on exit is
777
        /// undefined.</para>
778
        /// </remarks>
779

    
780
        public XsltExecutable Compile(TextReader input)
781
        {
782
            try {
783
                JStreamSource ss = new JStreamSource(new JDotNetReader(input));
784
                if (baseUri != null)
785
                {
786
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
787
                }
788

    
789
                XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(ss));
790
                executable.InternalProcessor = processor;
791
                return executable;
792
            }
793
            catch (JSaxonApiException ex) {
794
                throw new StaticError(ex);
795
            }
796
        }
797

    
798
        /// <summary>
799
        /// Compile a stylesheet, retrieving the source using a URI.
800
        /// </summary>
801
        /// <remarks>
802
        /// The document located via the URI is parsed using the <c>System.Xml</c> parser. This
803
        /// URI is used as the base URI of the stylesheet: the <c>BaseUri</c> property of the
804
        /// <c>Compiler</c> is ignored.
805
        /// </remarks>
806
        /// <param name="uri">The URI identifying the location where the stylesheet document can be
807
        /// found</param>
808
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
809
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
810
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
811
        /// once it has been compiled.</returns>
812

    
813
        public XsltExecutable Compile(Uri uri)
814
        {
815
            Object obj = XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
816
            if (obj is Stream)
817
            {
818

    
819
                // See bug issue #2306
820
                XsltExecutable executable = Compile((Stream)obj, uri.ToString(), true);
821
                executable.InternalProcessor = processor;
822
                return executable;
823

    
824
            }
825
            else
826
            {
827
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
828
            }
829
        }
830

    
831
        /// <summary>
832
		/// Compile a stylesheet, delivered using an <c>XmlReader</c>.
833
        /// </summary>
834
        /// <remarks>
835
		/// <para>
836
        /// The <c>XmlReader</c> is responsible for parsing the document; this method builds a tree
837
        /// representation of the document (in an internal Saxon format) and compiles it.
838
        /// The <c>XmlReader</c> will be used as supplied; it is the caller's responsibility to
839
        /// ensure that the settings of the <c>XmlReader</c> are consistent with the requirements
840
        /// of the XSLT specification (for example, that entity references are expanded and whitespace
841
        /// is preserved).
842
		/// </para>
843
		/// <para>
844
        /// If the <c>XmlReader</c> has a <c>BaseUri</c> property, then that property determines
845
        /// the base URI of the stylesheet module, which is used when resolving any <c>xsl:include</c>
846
        /// or <c>xsl:import</c> declarations. If the <c>XmlReader</c> has no <c>BaseUri</c>
847
        /// property, then the <c>BaseUri</c> property of the <c>Compiler</c> is used instead.
848
        /// An <c>ArgumentNullException</c> is thrown if this property has not been supplied.
849
		/// </para>
850
        /// </remarks>
851
        /// <param name="reader">The XmlReader (that is, the XML parser) used to supply the document containing
852
        /// the principal stylesheet module.</param>
853
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
854
        /// The XsltExecutable may be run as many times as required, in the same or a different
855
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
856
        /// once it has been compiled.</returns>
857

    
858

    
859
        public XsltExecutable Compile(XmlReader reader)
860
        {
861
            JDotNetPullProvider pp = new JDotNetPullProvider(reader);
862
            JPipelineConfiguration pipe = processor.Implementation.makePipelineConfiguration();
863
            pp.setPipelineConfiguration(pipe);
864
            // pp = new PullTracer(pp);  /* diagnostics */
865
            JPullSource source = new JPullSource(pp);
866
            String baseu = reader.BaseURI;
867
            if (baseu == null || baseu == String.Empty)
868
            {
869
                // if no baseURI is supplied by the XmlReader, use the one supplied to this Compiler
870
                if (baseUri == null)
871
                {
872
                    throw new ArgumentNullException("BaseUri");
873
                }
874
                baseu = Uri.EscapeUriString(baseUri.ToString());
875
                pp.setBaseURI(baseu);
876
            }
877
            source.setSystemId(baseu);
878
            try {
879

    
880
                XsltExecutable executable =  new XsltExecutable(xsltCompiler.compile(source));
881
                executable.InternalProcessor = processor;
882
                return executable;
883
            }
884
            catch (JSaxonApiException e) {
885
                throw new StaticError(e);
886
            }
887

    
888
            }
889

    
890
        /// <summary>
891
		/// Compile a stylesheet, located at an <c>XdmNode</c>. This may be a document node whose
892
        /// child is an <c>xsl:stylesheet</c> or <c>xsl:transform</c> element, or it may be
893
        /// the <c>xsl:stylesheet</c> or <c>xsl:transform</c> element itself.
894
        /// </summary>
895
        /// <param name="node">The document node or the outermost element node of the document
896
        /// containing the principal stylesheet module.</param>
897
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
898
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
899
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
900
        /// once it has been compiled.</returns>
901

    
902
        public XsltExecutable Compile(XdmNode node)
903
        {
904
            XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(node.Implementation));
905
            executable.InternalProcessor = processor;
906
            return executable;
907
        }
908

    
909
        /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
910
		/// processing instruction within a source document, and that match the given criteria.
911
        /// </summary>
912
        /// <param name="uri">The URI of the source document containing the xml-stylesheet processing instruction.</param>
913
        /// <param name="media">The media attribute to be matched. May be null, in which case the 
914
        /// "application/xml" mime type will be used when fetching the source document from the Uri.</param>
915
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
916
		/// <remarks>There are some limitations in the current implementation. Parameters of the xml-stylesheet 
917
		/// instruction other than the media type, are ignored. The
918
        /// <c>href</c> attribute must either reference an embedded stylesheet within the same
919
        /// document or a non-embedded external stylesheet.</remarks>
920

    
921
        public XsltExecutable CompileAssociatedStylesheet(Uri uri, String media)
922
        {
923

    
924
            Object obj = XmlResolver.GetEntity(uri, media == null ? "application/xml" : media, Type.GetType("System.IO.Stream"));
925
            if (obj is Stream)
926
            {
927
                JStreamSource ss = new JStreamSource(new JDotNetInputStream((Stream)obj));
928

    
929
                ss.setSystemId(Uri.EscapeUriString(uri.ToString()));
930
                try
931
                {
932

    
933
                    // See bug issue #2306
934
                    XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(xsltCompiler.getAssociatedStylesheet(ss, media, null, null)));
935
                    executable.InternalProcessor = processor;
936
                    return executable;
937

    
938
                }
939
                catch (JSaxonApiException e)
940
                {
941
                    throw new StaticError(e);
942
                }
943

    
944
            }
945
            else
946
            {
947
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
948

    
949
            }
950
         
951
        }
952

    
953
            /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
954
            /// processing instruction within a source document.
955
            /// </summary>
956
            /// <param name="source">The document node of the source document containing the
957
            /// xml-stylesheet processing instruction.</param>
958
            /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
959
            /// <remarks>There are some limitations in the current implementation. The media type
960
            /// is ignored, as are the other parameters of the xml-stylesheet instruction. The
961
            /// <c>href</c> attribute must either reference an embedded stylesheet within the same
962
            /// document or a non-embedded external stylesheet.</remarks>
963

    
964
            public XsltExecutable CompileAssociatedStylesheet(XdmNode source)
965
        {
966

    
967

    
968
            // TODO: lift the restrictions
969
            if (source == null || source.NodeKind != XmlNodeType.Document)
970
            {
971
                throw new ArgumentException("Source must be a document node");
972
            }
973
            IEnumerator kids = source.Children(Predicates.IsProcessingInstruction().And(Predicates.HasName("", "xml-stylesheet"))).GetEnumerator();
974
            while (kids.MoveNext())
975
            {
976
                XdmNode n = (XdmNode)kids.Current;
977
                // TODO: check the media type
978
                String href = JProcInstParser.getPseudoAttribute(n.StringValue, "href");
979
                if (href == null)
980
                {
981
                    throw new DynamicError("xml-stylesheet processing instruction has no href attribute");
982
                }
983
                String fragment = null;
984
                int hash = href.LastIndexOf('#');
985
                if (hash == 0)
986
                {
987
                    if (href.Length == 1)
988
                    {
989
                        throw new DynamicError("Relative URI of '#' is invalid");
990
                    }
991
                fragment = href.Substring(1);
992
                JNodeInfo target = ((JTreeInfo)source.value).selectID(fragment, true);
993
                XdmNode targetWrapper = null;
994
                if (target == null)
995
                {
996
                            // There's a problem here because the Microsoft XML parser doesn't
997
                            // report id values, so selectID() will never work. We work around that
998
                            // by looking for an attribute named "id" appearing on an xsl:stylesheet
999
                            // or xsl:transform element
1000
                            QName qid = new QName("", "id");
1001
                            IEnumerator en = source.EnumerateAxis(XdmAxis.Descendant);
1002
                            while (en.MoveNext())
1003
                            {
1004
                                XdmNode x = (XdmNode)en.Current;
1005
                                if (x.NodeKind == XmlNodeType.Element &&
1006
                                        x.NodeName.Uri == "http://www.w3.org/1999/XSL/Transform" &&
1007
                                        (x.NodeName.LocalName == "stylesheet" || x.NodeName.LocalName == "transform" &&
1008
                                        x.GetAttributeValue(qid) == fragment))
1009
                                {
1010
                                    targetWrapper = x;
1011
                                }
1012
                            }
1013
                        }
1014
                        else
1015
                        {
1016
                            targetWrapper = (XdmNode)XdmValue.Wrap(target);
1017
                            targetWrapper.SetProcessor(processor);
1018
                        }
1019
                        if (targetWrapper == null)
1020
                        {
1021
                            throw new DynamicError("No element with id='" + fragment + "' found");
1022
                        }
1023
                        return Compile(targetWrapper);
1024
                    }
1025
                    else if (hash > 0)
1026
                    {
1027
                        throw new NotImplementedException("href cannot identify an embedded stylesheet in a different document");
1028
                    }
1029
                    else
1030
                    {
1031
                        Uri uri = new Uri(n.BaseUri, href);
1032
                        return Compile(uri);
1033
                    }
1034
                
1035
            }
1036
            throw new DynamicError("xml-stylesheet processing instruction not found");
1037
        }
1038
    }
1039

    
1040
    /// <summary>
1041
    /// An <c>XsltExecutable</c> represents the compiled form of a stylesheet. To execute the stylesheet,
1042
	/// it must first be loaded to form an <see cref="XsltTransformer"/> or <see cref="Xslt30Transformer"/>.
1043
    /// </summary>
1044
    /// <remarks>
1045
    /// <para>An <c>XsltExecutable</c> is immutable, and therefore thread-safe. It is simplest to
1046
    /// load a new <c>XsltEvaluator</c> each time the stylesheet is to be run. However, the 
1047
    /// <c>XsltEvaluator</c> is serially reusable within a single thread.</para>
1048
    /// <para>An <c>XsltExecutable</c> is created by using one of the <c>Compile</c>
1049
	/// methods on the <see cref="XsltCompiler"/> class.</para>
1050
    /// </remarks>    
1051

    
1052
    [Serializable]
1053
    public class XsltExecutable
1054
    {
1055

    
1056
        // private JPreparedStylesheet pss;
1057
        private Processor processor;
1058
        private JXsltExecutable executable;
1059

    
1060
        // internal constructor
1061

    
1062
        internal XsltExecutable(JXsltExecutable executable)
1063
        {
1064
            //this.processor = proc;
1065
            this.executable = executable;
1066
        }
1067

    
1068
        internal Processor InternalProcessor
1069
        { 
1070
            set { processor = value;}
1071

    
1072
        }
1073

    
1074
        /// <summary>
1075
        /// Get the Processor that was used to create this XsltExecutable
1076
        /// </summary>
1077
        public Processor Processor
1078
        {
1079
            get { return processor; }
1080

    
1081
        }
1082

    
1083
        /// <summary>
1084
        /// Load the stylesheet to prepare it for execution.
1085
        /// </summary>
1086
        /// <returns>
1087
        /// An <c>XsltTransformer</c>. The returned <c>XsltTransformer</c> can be used to
1088
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
1089
        /// </returns>
1090

    
1091
        public XsltTransformer Load()
1092
        {
1093
           // JXsltController c = pss.newController();
1094
            return new XsltTransformer(executable.load());
1095
        }
1096

    
1097

    
1098

    
1099
        /// <summary>
1100
		/// Load the stylesheet to prepare it for execution. This version of the <c>load()</c> method
1101
        /// creates an <code>Xslt30Transformer</code> which offers interfaces for stylesheet
1102
        /// invocation corresponding to those described in the XSLT 3.0 specification. It can be used
1103
        /// with XSLT 2.0 or XSLT 3.0 stylesheets, and in both cases it offers new XSLT 3.0 functionality such
1104
        /// as the ability to supply parameters to the initial template, or the ability to invoke
1105
        /// stylesheet-defined functions, or the ability to return an arbitrary sequence as a result
1106
        /// without wrapping it in a document node.
1107
        /// </summary>
1108
        /// <returns>
1109
        /// An <c>Xslt30Transformer</c>. The returned <c>Xslt30Transformer</c> can be used to
1110
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
1111
        /// </returns>
1112

    
1113
        public Xslt30Transformer Load30()
1114
        {
1115
            return new Xslt30Transformer(executable.load30());
1116
        }
1117

    
1118
        /// <summary>
1119
        /// Output an XML representation of the compiled code of the stylesheet, for purposes of 
1120
        /// diagnostics and instrumentation.
1121
        /// </summary>
1122
        /// <param name="destination">The destination for the diagnostic output</param>
1123

    
1124
        public void Explain(XmlDestination destination)
1125
        {
1126
            executable.explain(destination.GetUnderlyingDestination());
1127
        }
1128

    
1129
        /// <summary>
1130
        /// Escape hatch to the underlying Java implementation object.
1131
        /// </summary>
1132

    
1133
        public JXsltExecutable Implementation
1134
        {
1135
            get
1136
            {
1137
                return executable;
1138
            }
1139
        }
1140

    
1141
        /// <summary>
1142
        /// Get the whitespace stripping policy defined by this stylesheet, that is, the policy
1143
        /// defined by the <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> elements in the stylesheet.
1144
        /// </summary>
1145
        /// <returns> a newly constructed <c>WhitespacePolicy</c> based on the declarations in this
1146
        /// stylesheet. This policy can be used as input to a <see cref="DocumentBuilder"/>.</returns>
1147
        
1148
        public WhitespacePolicy getWhitespaceStrippingPolicy() {
1149
            return new WhitespacePolicy(executable);
1150
        }
1151

    
1152

    
1153
        /// <summary>
1154
        /// Get the names of the <c>xsl:param</c> elements defined in this stylesheet, with details
1155
        /// of each parameter including its required type, and whether it is required or optional.
1156
        /// </summary>
1157
        /// <returns>
1158
		/// a <c>Dictionary</c> whose keys are the names of global parameters in the stylesheet,
1159
		/// and whose values are <see cref="Saxon.Api.XsltExecutable+ParameterDetails"/> objects giving information about the
1160
        /// corresponding parameter.
1161
        /// </returns>
1162
        public Dictionary<QName, ParameterDetails> GetGlobalParameters()
1163
        {
1164
            java.util.HashMap globals = executable.getGlobalParameters();
1165
            Dictionary<QName, ParameterDetails> params1 = new Dictionary<QName, ParameterDetails>();
1166
            int count = globals.size();
1167
            object[] names = globals.keySet().toArray();
1168
            for (int i = 0; i < count; i++) {
1169
                JXsltExecutable.ParameterDetails details = (JXsltExecutable.ParameterDetails)globals.get(names[i]);
1170
                XdmSequenceType sType = XdmSequenceType.FromSequenceType(details.getUnderlyingDeclaredType());
1171
                sType.itemType.SetJXdmItemType(details.getDeclaredItemType());
1172
                params1.Add(new QName((net.sf.saxon.s9api.QName)names[i]), new ParameterDetails(sType, false));
1173

    
1174
            }
1175
            return params1;
1176
        }
1177

    
1178
        /// <summary>
1179
        /// Information about a global parameter to a stylesheet.
1180
        /// </summary>
1181

    
1182
        public class ParameterDetails
1183
        {
1184
            private XdmSequenceType type;
1185
            private bool isRequired;
1186

    
1187
            /// <summary>
1188
            /// Create parameter details.
1189
            /// </summary>
1190
            /// <param name="type">The declared type of the parameter.</param>
1191
            /// <param name="isRequired">Indicates whether the parameter is required or optional.</param>
1192
            
1193
            public ParameterDetails(XdmSequenceType type, bool isRequired)
1194
            {
1195
                this.type = type;
1196
                this.isRequired = isRequired;
1197
            }
1198

    
1199
            /// <summary>
1200
            /// Gets the declared item type of the parameter.
1201
            /// </summary>
1202
            /// <returns>The type defined in the <code>as</code> attribute of the <code>xsl:param</code> element,
1203
            /// without its occurrence indicator</returns>
1204
            public XdmItemType GetDeclaredItemType()
1205
            {
1206
                return type.itemType;
1207
            }
1208

    
1209

    
1210
            /// <summary>
1211
            /// Gets the declared cardinality of the parameter.
1212
            /// </summary>
1213
            /// <returns>The occurrence indicator from the type appearing in the <code>as</code> attribute
1214
            /// of the <code>xsl:param</code> element</returns>
1215

    
1216
            public char GetDeclaredCardinality()
1217
            {
1218
                return type.occurrenceIn;
1219
            }
1220

    
1221
            /// <summary>
1222
            /// Gets the underlying declared type of the parameter.
1223
            /// </summary>
1224
            /// <returns>The underlying declared type.</returns>
1225

    
1226
            public XdmSequenceType GetUnderlyingDeclaredType()
1227
            {
1228
                return type;
1229
            }
1230

    
1231

    
1232
            /// <summary>
1233
            /// Ask whether the parameter is required (mandatory) or optional
1234
            /// </summary>
1235
            /// <returns><c>true</c> if the parameter is mandatory (<code>required="yes"</code>), false
1236
            /// if it is optional.</returns>
1237

    
1238
            public bool IsRequired
1239
            {
1240
                set { this.isRequired = value; }
1241
                get { return this.isRequired; }
1242

    
1243
            }
1244
        }
1245

    
1246

    
1247

    
1248

    
1249
    }
1250

    
1251

    
1252
    /// <summary inherits="XdmDestination">
1253
    /// An <c>XsltTransformer</c> represents a compiled and loaded stylesheet ready for execution.
1254
    /// The <c>XsltTransformer</c> holds details of the dynamic evaluation context for the stylesheet.
1255
    /// </summary>
1256
    /// <remarks>
1257
    /// <para>An <c>XsltTransformer</c> must not be used concurrently in multiple threads. It is safe,
1258
    /// however, to reuse the object within a single thread to run the same stylesheet several times.
1259
    /// Running the stylesheet does not change the context that has been established.</para>
1260
    /// <para>An <c>XsltTransformer</c> is always constructed by running the <c>Load</c> method of
1261
    /// an <c>XsltExecutable</c>.</para>
1262
	/// <para>The <see cref="Xslt30Transformer"/> class provides invocation options that are more closely aligned
1263
    /// with the XSLT 3.0 specification, for example streamed evaluation. However, both <c>XsltTransformer</c> 
1264
	/// and <c>Xslt30Transformer</c> can be used irrespective of the XSLT language version used in the stylesheet.</para>
1265
    /// </remarks>
1266

    
1267
    [Serializable]
1268
    public class XsltTransformer : XmlDestination
1269
    {
1270

    
1271
        /* private JXsltController controller;
1272
      
1273
         private JStreamSource streamSource;
1274
         private GlobalParameterSet globalParameters;
1275
         private bool baseOutputUriWasSet = false;*/
1276
        private XmlDestination xmlDestination;
1277
        private StandardLogger traceFunctionDestination;
1278
        private IMessageListener messageListener;
1279
        private IMessageListener2 messageListener2;
1280
        private IResultDocumentHandler resultDocumentHandler;
1281
        private QName initialTemplateName;
1282
        private XdmNode initialContextNode;
1283
        private JXsltTransformer transformer;
1284

    
1285
        // internal constructor
1286

    
1287
        internal XsltTransformer(JXsltTransformer transformer)
1288
        {
1289
            this.transformer = transformer;
1290
        }
1291

    
1292
        /// <summary>
1293
        /// The global context item for the stylesheet, as a node.
1294
        /// </summary>
1295
        /// <remarks><para>Although XSLT 3.0 allows the global context item to be any item,
1296
        /// this interface only allows it to be a node.
1297
        /// Most commonly it will be a document node, which might be constructed
1298
        /// using the <c>Build</c> method of the <c>DocumentBuilder</c> object.</para>
1299
        /// <para>Note that this can be inefficient if the stylesheet uses <c>xsl:strip-space</c>
1300
        /// to strip whitespace, or <c>input-type-annotations="strip"</c> to remove type
1301
        /// annotations, since this will result in the transformation operating on a virtual document
1302
        /// implemented as a view or wrapper of the supplied document.</para>
1303
        /// </remarks>
1304

    
1305
        public XdmNode InitialContextNode
1306
        {
1307
            get {
1308
                JNodeInfo node = transformer.getInitialContextNode().getUnderlyingNode();
1309
                return node == null ? null : ((XdmNode)XdmValue.Wrap(node)); }
1310
            set { transformer.setInitialContextNode(value == null ? null : (net.sf.saxon.s9api.XdmNode)XdmValue.FromGroundedValueToJXdmValue(value.value)); }
1311
        }
1312

    
1313
        /// <summary>
1314
        /// Supply the principal input document for the transformation in the form of a stream.
1315
        /// </summary>
1316
        /// <remarks>
1317
        /// <para>If this method is used, the <c>InitialContextNode</c> is ignored.</para>
1318
        /// <para>The supplied stream will be consumed by the <c>Run()</c> method.
1319
        /// Closing the input stream after use is the client's responsibility.</para>
1320
        /// <para>A base URI must be supplied in all cases. It is used to resolve relative
1321
        /// URI references appearing within the input document.</para>
1322
        /// <para>Schema validation is applied to the input document according to the value of
1323
        /// the <c>SchemaValidationMode</c> property.</para>
1324
        /// <para>Whitespace stripping is applied according to the value of the
1325
        /// <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> declarations in the stylesheet.</para>
1326
        /// </remarks>
1327
        /// <param name="input">
1328
        /// The stream containing the source code of the principal input document to the transformation. The document
1329
        /// node at the root of this document will be the global context item for the transformation.
1330
        /// </param>
1331
        /// <param name="baseUri">
1332
        /// The base URI of the principal input document. This is used for example by the <c>document()</c>
1333
        /// function if the document contains links to other documents in the form of relative URIs.</param>
1334

    
1335
        public void SetInputStream(Stream input, Uri baseUri)
1336
        {
1337
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
1338
            transformer.setSource(streamSource);
1339
        }
1340

    
1341
        /// <summary>
1342
		/// The initial mode for the stylesheet. This is either a <c>QName</c>, for a 
1343
        /// specific mode, or null, for the default mode.
1344
        /// </summary>
1345
        /// <remarks>
1346
        /// The default mode will usually be the unnamed mode, but if the stylesheet declares a
1347
        /// named mode as the default mode, then supplying null as the <c>InitialMode</c> invokes this default.
1348
        /// </remarks>
1349

    
1350
        public QName InitialMode
1351
        {
1352
            get
1353
            {
1354
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
1355
                if (mode == null)
1356
                {
1357
                    return null;
1358
                }
1359

    
1360
                return QName.FromClarkName(mode.getClarkName());
1361
            }
1362
            set
1363
            {
1364
               transformer.setInitialMode(value == null ? null : net.sf.saxon.s9api.QName.fromEQName(value.EQName));
1365
            }
1366
        }
1367

    
1368

    
1369
        /// <summary>
1370
		/// The initial template for the stylesheet. This is either a <c>QName</c>, for a 
1371
        /// named template, or null, if no initial template has been set.
1372
        /// </summary>
1373
        /// <remarks>
1374
        /// If the stylesheet is to be invoked by calling the template named <c>xsl:initial-template</c>,
1375
		/// then the <c>InitialTemplate</c> property should be set to this <c>QName</c> explicitly.
1376
        /// </remarks>
1377
        /// <exception cref="DynamicError">Setting this property to the name of a template
1378
		/// that does not exist in the stylesheet throws a <c>DynamicError</c> with error 
1379
        /// code XTDE0040. Setting it to the name of a template that has template
1380
		/// parameters throws a <c>DynamicError</c> with error code XTDE0060.</exception>
1381

    
1382
        public QName InitialTemplate
1383
        {
1384
            get
1385
            {
1386
                return initialTemplateName;
1387
            }
1388
            set
1389
            {
1390
                initialTemplateName = value;
1391
                transformer.setInitialTemplate(initialTemplateName.UnderlyingQName());
1392
            }
1393
        }
1394

    
1395
        /// <summary>
1396
        /// The base output URI, which acts as the base URI for resolving the <c>href</c>
1397
        /// attribute of <c>xsl:result-document</c>.
1398
        /// </summary>
1399

    
1400
        public Uri BaseOutputUri
1401
        {
1402
            get
1403
            {
1404
                return new Uri(transformer.getBaseOutputURI());
1405
            }
1406
            set
1407
            {
1408
                transformer.setBaseOutputURI(value.ToString());
1409
            }
1410
        }
1411

    
1412

    
1413
        /// <summary>
1414
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
1415
        /// loaded using the <c>doc()</c>, <c>document()</c>, or <c>collection()</c> functions.
1416
        /// </summary>
1417

    
1418
        public SchemaValidationMode SchemaValidationMode
1419
        {
1420
            get
1421
            {
1422
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
1423
                {
1424
                    case JValidation.STRICT:
1425
                        return SchemaValidationMode.Strict;
1426
                    case JValidation.LAX:
1427
                        return SchemaValidationMode.Lax;
1428
                    case JValidation.STRIP:
1429
                        return SchemaValidationMode.None;
1430
                    case JValidation.PRESERVE:
1431
                        return SchemaValidationMode.Preserve;
1432
                    case JValidation.DEFAULT:
1433
                    default:
1434
                        return SchemaValidationMode.Unspecified;
1435
                }
1436
            }
1437

    
1438
            set
1439
            {
1440
                switch (value)
1441
                {
1442
                    case SchemaValidationMode.Strict:
1443
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
1444
                        break;
1445
                    case SchemaValidationMode.Lax:
1446
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
1447
                        break;
1448
                    case SchemaValidationMode.None:
1449
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
1450
                        break;
1451
                    case SchemaValidationMode.Preserve:
1452
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
1453
                        break;
1454
                    case SchemaValidationMode.Unspecified:
1455
                    default:
1456
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
1457
                        break;
1458
                }
1459
            }
1460
        }
1461

    
1462

    
1463

    
1464

    
1465

    
1466
        /// <summary>
1467
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
1468
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
1469
        /// </summary>
1470

    
1471
        public XmlResolver InputXmlResolver
1472
        {
1473
            get
1474
            {
1475
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
1476
            }
1477
            set
1478
            {
1479
                transformer.setURIResolver(new JDotNetURIResolver(value));
1480
            }
1481
        }
1482

    
1483
        /// <summary>
1484
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
1485
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
1486
        /// attribute.
1487
        /// </summary>
1488
        /// <remarks>
1489
        /// In the absence of a user-supplied result document handler, the <c>href</c>
1490
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
1491
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
1492
        /// and the resulting absolute URI must identify a writable resource (typically
1493
        /// a file in filestore, using the <c>file:</c> URI scheme).
1494
        /// </remarks>
1495

    
1496
        public IResultDocumentHandler ResultDocumentHandler
1497
        {
1498
            get
1499
            {
1500
                return resultDocumentHandler;
1501
            }
1502
            set
1503
            {
1504
                resultDocumentHandler = value;
1505
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
1506
            }
1507
        }
1508

    
1509
        /// <summary>
1510
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1511
		/// </summary>
1512
		/// <remarks> 
1513
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1514
        /// the processor will then invoke the listener once for each message generated during
1515
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1516
        /// representing a document node.</para>
1517
        /// <para>If no message listener is supplied by the caller, message information will be written to
1518
        /// the standard error stream.</para>
1519
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1520
        /// on the message object will usually generate an acceptable representation of the
1521
        /// message.</para>
1522
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1523
        /// the message is first notified using this interface, and then an exception is thrown
1524
        /// which terminates the transformation.</para>
1525
        /// </remarks>
1526

    
1527
        public IMessageListener MessageListener
1528
        {
1529
            set
1530
            {
1531
                messageListener = value;
1532
                transformer.setMessageListener(new MessageListenerProxy(value));
1533
            }
1534
            get
1535
            {
1536
                return messageListener;
1537
            }
1538
        }
1539

    
1540

    
1541

    
1542
        /// <summary>
1543
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1544
        /// </summary>
1545
        /// <remarks> 
1546
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1547
        /// the processor will then invoke the listener once for each message generated during
1548
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1549
        /// representing a document node.</para>
1550
        /// <para>If no message listener is supplied by the caller, message information will be written to
1551
        /// the standard error stream.</para>
1552
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1553
        /// on the message object will usually generate an acceptable representation of the
1554
        /// message.</para>
1555
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1556
        /// the message is first notified using this interface, and then an exception is thrown
1557
        /// which terminates the transformation.</para>
1558
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
1559
        /// in allowing the error code supplied to xsl:message to be notified</para>
1560
        /// </remarks>
1561

    
1562
        public IMessageListener2 MessageListener2
1563
        {
1564
            set
1565
            {
1566
                messageListener2 = value;
1567
                transformer.setMessageListener(new MessageListenerProxy2(value));
1568
            }
1569
            get
1570
            {
1571
                return messageListener2;
1572
            }
1573
        }
1574

    
1575
        /// <summary>
1576
        /// Destination for output of messages using the <c>trace()</c> function.
1577
        /// </summary>
1578
		/// <remarks> 
1579
		/// <para>If no message listener is supplied by the caller, message information will be written to
1580
		/// the standard error stream.</para>
1581
        /// <para>The supplied destination is ignored if a <c>TraceListener</c> is in use.</para>
1582
        /// </remarks>
1583

    
1584
        public StandardLogger TraceFunctionDestination
1585
        {
1586
            set
1587
            {
1588
                traceFunctionDestination = value;
1589
                transformer.setTraceFunctionDestination(value);
1590
            }
1591
            get
1592
            {
1593
                return traceFunctionDestination;
1594
            }
1595
        }
1596

    
1597

    
1598

    
1599
        /// <summary>
1600
        /// Set the value of a stylesheet parameter.
1601
        /// </summary>
1602
        /// <param name="name">The name of the parameter, expressed
1603
        /// as a QName. If a parameter of this name has been declared in the
1604
        /// stylesheet, the given value will be assigned to the variable. If the
1605
        /// variable has not been declared, calling this method has no effect (it is
1606
        /// not an error).</param>
1607
        /// <param name="value">The value to be given to the parameter.
1608
        /// If the parameter declaration defines a required type for the variable, then
1609
        /// this value will be converted in the same way as arguments to function calls
1610
        /// (for example, numeric promotion is applied).</param>
1611

    
1612
        public void SetParameter(QName name, XdmValue value)
1613
        {
1614
            transformer.setParameter(net.sf.saxon.s9api.QName.fromEQName(name.EQName), net.sf.saxon.s9api.XdmValue.wrap(value.value));
1615
        }
1616

    
1617
        public JDestination GetUnderlyingDestination() {
1618
            return transformer;
1619
        }
1620

    
1621
        public JXsltTransformer Implemmentation
1622
        {
1623
            get
1624
            {
1625
                return transformer;
1626

    
1627
            }
1628
        }
1629

    
1630

    
1631

    
1632
        /// <summary>
1633
		/// The destination for the result of the transformation. The class <c>XmlDestination</c> is an abstraction 
1634
        /// that allows a number of different kinds of destination to be specified.
1635
        /// </summary>
1636
        /// <remarks>
1637
        /// <para>The Destination can be used to chain transformations into a pipeline, by using one
1638
        /// <c>XsltTransformer</c> as the destination of another.</para>
1639
        /// </remarks>
1640

    
1641
        public XmlDestination Destination
1642
        {
1643
            get
1644
            {
1645
                return this.xmlDestination;
1646
            }
1647
            set
1648
            {
1649
                this.xmlDestination = value;
1650
                transformer.setDestination(value.GetUnderlyingDestination());
1651
            }
1652

    
1653
        }
1654

    
1655

    
1656
        /// <summary>
1657
		/// Close the <c>Destination</c>, releasing any resources that need to be released.
1658
        /// </summary>
1659
        /// <remarks>
1660
        /// This method is called by the system on completion of a query or transformation.
1661
		/// Some kinds of <c>Destination</c> may need to close an output stream, others might
1662
        /// not need to do anything. The default implementation does nothing.
1663
        /// </remarks>
1664

    
1665
        public void Close()
1666
        {
1667
            transformer.close();
1668

    
1669
        }
1670

    
1671
		// internal method
1672

    
1673
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
1674
        {
1675

    
1676
            JController controller = transformer.getUnderlyingController();
1677
                JPipelineConfiguration pipe = controller.getConfiguration().makePipelineConfiguration();
1678
                JReceiver r = destination.GetUnderlyingDestination().getReceiver(pipe, controller.getExecutable().getPrimarySerializationProperties());
1679
                pipe.setController(controller);
1680
                return r;
1681
            //}
1682
        }
1683

    
1684
        /// <summary>
1685
        /// Run the transformation, sending the result to a specified destination.
1686
        /// </summary>
1687
        /// <param name="destination">
1688
        /// The destination for the results of the stylesheet. The class <c>XmlDestination</c>
1689
        /// is an abstraction that allows a number of different kinds of destination
1690
        /// to be specified.
1691
        /// </param>
1692
		/// <exception cref="DynamicError">Throws a <c>DynamicError</c> if the transformation
1693
        /// fails.</exception>
1694

    
1695
        public void Run(XmlDestination destination)
1696
        {
1697
            if (destination == null)
1698
            {
1699
                throw new DynamicError("Destination is null");
1700
            }
1701
           
1702
            try
1703
            {
1704
                transformer.setDestination(destination.GetUnderlyingDestination());
1705
                transformer.transform() ;
1706
               
1707
            }
1708
            catch (JSaxonApiException err)
1709
            {
1710
                throw new DynamicError(err);
1711
            }
1712
        }
1713

    
1714
        /*internal void applyTemplatesToSource(JStreamSource streamSource, JReceiver outi){
1715

    
1716
           
1717
            if (controller.getInitialMode().isDeclaredStreamable()) {
1718
                controller.applyStreamingTemplates(streamSource, outi);
1719
            }
1720
        } */
1721

    
1722
        /// <summary>
1723
        /// Escape hatch to the underlying Java implementation
1724
        /// </summary>
1725

    
1726
        public JController Implementation
1727
        {
1728
            get { return transformer.getUnderlyingController(); }
1729
        }
1730

    
1731

    
1732
    }
1733

    
1734
    /// <summary>
1735
	/// <c>RecoveryPolicy</c> is an enumeration of the different actions that can be taken when a "recoverable error" occurs.
1736
    /// </summary>  
1737

    
1738
    public enum RecoveryPolicy
1739
    {
1740
        /// <summary>
1741
        /// Ignore the error, take the recovery action, do not produce any message
1742
        /// </summary>
1743
        RecoverSilently,
1744

    
1745
        /// <summary>
1746
        /// Take the recovery action after outputting a warning message
1747
        /// </summary>
1748
        RecoverWithWarnings,
1749

    
1750
        /// <summary>
1751
        /// Treat the error as fatal
1752
        /// </summary>
1753
        DoNotRecover
1754

    
1755
    }
1756

    
1757

    
1758

    
1759
    /// <summary>An <c>IResultDocumentHandler</c> can be nominated to handle output
1760
    /// produced by the <c>xsl:result-document</c> instruction in an XSLT stylesheet.
1761
    /// </summary>
1762
    /// <remarks>
1763
    /// <para>This interface affects any <c>xsl:result-document</c> instruction
1764
    /// executed by the stylesheet, provided that it has an <c>href</c> attribute.</para> 
1765
    /// <para>If no <c>IResultDocumentHandler</c> is nominated (in the
1766
    /// <c>IResultDocumentHandler</c> property of the <c>XsltTransformer</c>), the output
1767
    /// of <code>xsl:result-document</code> is serialized, and is written to the file
1768
    /// or other resource identified by the URI in the <c>href</c> attribute, resolved
1769
    /// (if it is relative) against the URI supplied in the <c>BaseOutputUri</c> property
1770
    /// of the <c>XsltTransformer</c>.</para>
1771
    /// <para>If an <c>IResultDocumentHandler</c> is nominated, however, its
1772
    /// <c>HandleResultDocument</c> method will be called whenever an <c>xsl:result-document</c>
1773
    /// instruction with an <c>href</c> attribute is evaluated, and the generated result tree
1774
    /// will be passed to the <c>XmlDestination</c> returned by that method.</para> 
1775
    /// </remarks>
1776

    
1777
    public interface IResultDocumentHandler
1778
    {
1779

    
1780
        /// <summary> Handle output produced by the <c>xsl:result-document</c>
1781
        /// instruction in an XSLT stylesheet. This method is called by the XSLT processor
1782
        /// when an <c>xsl:result-document</c> with an <c>href</c> attribute is evaluated.
1783
        /// </summary>
1784
        /// <param name="href">An absolute or relative URI. This will be the effective value of the 
1785
        /// <c>href</c> attribute of the <c>xsl:result-document</c> in the stylesheet.</param>
1786
        /// <param name="baseUri">The base URI that should be used for resolving the value of
1787
        /// <c>href</c> if it is relative. This will always be the value of the <c>BaseOutputUri</c>
1788
        /// property of the <c>XsltTransformer</c>.</param>
1789
        /// <returns>An <c>XmlDestination</c> to handle the result tree produced by the
1790
        /// <c>xsl:result-document</c> instruction. The <c>Close</c> method of the returned
1791
        /// <c>XmlDestination</c> will be called when the output is complete.</returns>
1792
        /// <remarks>
1793
        /// <para>The XSLT processor will ensure that the stylesheet cannot create
1794
        /// two distinct result documents which are sent to the same URI. It is the responsibility
1795
        /// of the <c>IResultDocumentHandler</c> to ensure that two distinct result documents are
1796
        /// not sent to the same <c>XmlDestination</c>. Failure to observe this rule can result
1797
        /// in output streams being incorrectly closed.
1798
        /// </para>
1799
        /// <para>Note that more than one result document can be open at the same time,
1800
        /// and that the order of opening, writing, and closing result documents chosen
1801
        /// by the processor does not necessarily bear any direct resemblance to the way
1802
        /// that the XSLT source code is written.</para></remarks>
1803
        /**public**/
1804
        XmlDestination HandleResultDocument(string href, Uri baseUri);
1805

    
1806
    }
1807

    
1808
    ///<summary>Internal wrapper class for <c>IResultDocumentHandler</c></summary>
1809
    internal class ResultDocumentHandlerWrapper : JResultDocumentResolver
1810
    {
1811

    
1812
        private IResultDocumentHandler handler;
1813
        private ArrayList resultList = new ArrayList();
1814
        private ArrayList destinationList = new ArrayList();
1815
        private JPipelineConfiguration pipe;
1816

    
1817
        /// <summary>
1818
        /// Initializes a new instance of the <see cref="Saxon.Api.ResultDocumentHandlerWrapper"/> class.
1819
        /// </summary>
1820
        /// <param name="handler">Handler.</param>
1821
        /// <param name="pipe">Pipe.</param>
1822
        public ResultDocumentHandlerWrapper(IResultDocumentHandler handler, JPipelineConfiguration pipe)
1823
        {
1824
            this.handler = handler;
1825
            this.pipe = pipe;
1826
        }
1827

    
1828

    
1829

    
1830

    
1831
        /// <summary>
1832
        /// Close the specified result.
1833
        /// </summary>
1834
        /// <param name="result">Result.</param>
1835
        public void close(JResult result)
1836
        {
1837
            for (int i = 0; i < resultList.Count; i++)
1838
            {
1839
                if (Object.ReferenceEquals(resultList[i], result))
1840
                {
1841
                    ((XmlDestination)destinationList[i]).GetUnderlyingDestination().close();
1842
                    resultList.RemoveAt(i);
1843
                    destinationList.RemoveAt(i);
1844
                    return;
1845
                }
1846
            }
1847
        }
1848

    
1849
        /// <summary>
1850
        /// Resolve the specified href and baseString.
1851
        /// </summary>
1852
        /// <param name="href">Href.</param>
1853
        /// <param name="baseString">Base string.</param>
1854
        public JReceiver resolve(net.sf.saxon.expr.XPathContext xpc, string href, string baseString, net.sf.saxon.serialize.SerializationProperties sp)
1855
        {
1856
            Uri baseUri;
1857
            try
1858
            {
1859
                baseUri = new Uri(baseString);
1860
            }
1861
            catch (System.UriFormatException err)
1862
            {
1863
                throw new JTransformerException("Invalid base output URI " + baseString, err);
1864
            }
1865
            XmlDestination destination = handler.HandleResultDocument(href, baseUri);
1866
            JReceiver result = destination.GetUnderlyingDestination().getReceiver(pipe, sp);
1867
            resultList.Add(result);
1868
            destinationList.Add(destination);
1869
            return result;
1870
        }
1871
    }
1872

    
1873
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1874
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1875
    /// </summary>
1876
    /// <remarks>
1877
    /// <para>This interface affects any <c>xsl:message</c> instruction
1878
    /// executed by the stylesheet.</para> 
1879
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1880
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1881
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1882
    /// output stream.</para>
1883
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1884
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1885
    /// instruction is evaluated.</para> 
1886
    /// </remarks>
1887

    
1888
    public interface IMessageListener
1889
    {
1890

    
1891
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1892
        /// in the stylesheet
1893
        /// </summary>
1894
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1895
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1896
        /// <c>GetStringValue()</c></param>
1897
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1898
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1899
        /// module and the line number of the <c>xsl:message</c></param>
1900

    
1901
        /**public**/
1902
        void Message(XdmNode content, bool terminate, IXmlLocation location);
1903

    
1904
    }
1905

    
1906

    
1907

    
1908
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1909
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1910
    /// </summary>
1911
    /// <remarks>
1912
    /// <para>This interface affects any <c>xsl:message</c> instruction
1913
    /// executed by the stylesheet.</para> 
1914
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1915
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1916
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1917
    /// output stream.</para>
1918
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1919
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1920
    /// instruction is evaluated.</para> 
1921
    /// <para>The <c>MessageListener2</c> interface differs from <c>MessageListener</c>
1922
    /// in allowing the error code supplied to <c>xsl:message</c> to be made available.</para>
1923
    /// </remarks>
1924

    
1925
    public interface IMessageListener2
1926
    {
1927

    
1928
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1929
        /// in the stylesheet
1930
        /// </summary>
1931
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1932
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1933
        /// <c>GetStringValue()</c></param>
1934
        /// <param name="errorCode">a QName containing the error supplied to the called on xsl:message, or its default of err:XTM9000.</param>
1935
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1936
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1937
        /// module and the line number of the <c>xsl:message</c></param>
1938

    
1939
        /**public**/
1940
        void Message(XdmNode content, QName errorCode,  bool terminate, IXmlLocation location);
1941

    
1942
    }
1943

    
1944
    /// <summary>
1945
    /// An <c>IXmlLocation</c> represents the location of a node within an XML document.
1946
    /// It is in two parts: the base URI (or system ID) of the external entity (which will usually
1947
    /// be the XML document entity itself), and the line number of a node relative
1948
    /// to the base URI of the containing external entity.
1949
    /// </summary>
1950

    
1951
    public interface IXmlLocation
1952
    {
1953

    
1954
        /// <summary>
1955
        /// The base URI (system ID) of an external entity within an XML document.
1956
        /// Set to null if the base URI is not known (for example, for an XML document
1957
        /// created programmatically where no base URI has been set up).
1958
        /// </summary>
1959

    
1960
        /**public**/
1961
        Uri BaseUri { get; set; }
1962

    
1963
        /// <summary>
1964
        /// The line number of a node relative to the start of the external entity.
1965
        /// The value -1 indicates that the line number is not known or not applicable.
1966
        /// </summary>
1967

    
1968
        /**public**/
1969
        int LineNumber { get; set; }
1970
    }
1971

    
1972

    
1973
    /// <summary>
1974
	/// Xml location. An implementation of <c>IXmlLocation</c>.
1975
    /// </summary>
1976
    internal class XmlLocation : IXmlLocation
1977
    {
1978
        private Uri baseUri;
1979
        private int lineNumber;
1980
        public Uri BaseUri
1981
        {
1982
            get { return baseUri; }
1983
            set { baseUri = value; }
1984
        }
1985
        public int LineNumber
1986
        {
1987
            get { return lineNumber; }
1988
            set { lineNumber = value; }
1989
        }
1990
    }
1991

    
1992

    
1993
    /// <summary>
1994
    /// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener</c> that can receive 
1995
    /// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1996
    /// </summary>
1997
    [Serializable]
1998
    internal class MessageListenerProxy : net.sf.saxon.s9api.MessageListener
1999
    {
2000

    
2001
        public IMessageListener listener;
2002

    
2003
        /// <summary>
2004
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
2005
        /// </summary>
2006
        /// <param name="ml">ml.</param>
2007
        public MessageListenerProxy(IMessageListener ml)
2008
        {
2009
            listener = ml;
2010
        }
2011

    
2012

    
2013
        public void message(net.sf.saxon.s9api.XdmNode xn, bool b, SourceLocator sl)
2014
        {
2015
            IXmlLocation location = new XmlLocation();
2016
            location.BaseUri = new Uri(sl.getSystemId());
2017
            location.LineNumber = sl.getLineNumber();
2018
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), b, location);
2019
        }
2020
    }
2021

    
2022

    
2023

    
2024
    /// <summary>
2025
	/// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener2</c> that can receive 
2026
	/// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
2027
    /// </summary>
2028
    [Serializable]
2029
    internal class MessageListenerProxy2 : net.sf.saxon.s9api.MessageListener2
2030
    {
2031

    
2032
        public IMessageListener2 listener;
2033

    
2034
        /// <summary>
2035
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
2036
        /// </summary>
2037
        /// <param name="ml">ml.</param>
2038
        public MessageListenerProxy2(IMessageListener2 ml)
2039
        {
2040
            listener = ml;
2041
        }
2042

    
2043

    
2044
        public void message(net.sf.saxon.s9api.XdmNode xn, net.sf.saxon.s9api.QName qn, bool b, SourceLocator sl)
2045
        {
2046
            IXmlLocation location = new XmlLocation();
2047
            location.BaseUri = new Uri(sl.getSystemId());
2048
            location.LineNumber = sl.getLineNumber();
2049
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), new QName(qn),b, location);
2050
        }
2051
    }
2052

    
2053

    
2054

    
2055
    /// <summary>An <code>Xslt30Transformer</code> represents a compiled and loaded stylesheet ready for execution.
2056
    /// The <code>Xslt30Transformer</code> holds details of the dynamic evaluation context for the stylesheet.</summary>
2057
    /// <remarks><para>The <code>Xslt30Transformer</code> differs from <see cref="XsltTransformer"/> 
2058
    /// in supporting new options
2059
    /// for invoking a stylesheet, corresponding to facilities defined in the XSLT 3.0 specification. However,
2060
    /// it is not confined to use with XSLT 3.0, and most of the new invocation facilities (for example,
2061
    /// calling a stylesheet-defined function directly) work equally well with XSLT 2.0 and in some cases
2062
    /// XSLT 1.0 stylesheets.</para>
2063
    /// <para>An <code>Xslt30Transformer</code> must not be used concurrently in multiple threads.
2064
    /// It is safe, however, to reuse the object within a single thread to run the same
2065
    /// stylesheet several times. Running the stylesheet does not change the context
2066
    /// that has been established.</para>
2067
    /// <para>An <code>Xslt30Transformer</code> is always constructed by running the <code>Load30</code>
2068
    /// method of an <see cref="XsltExecutable"/>.</para>
2069
    /// <para>Unlike <code>XsltTransformer</code>, an <code>Xslt30Transformer</code> is not a <code>Destination</code>.
2070
    /// To pipe the results of one transformation into another, the target should be an <code>XsltTransfomer</code>
2071
    /// rather than an <code>Xslt30Transformer</code>.</para>
2072
    /// <para>Evaluation of an Xslt30Transformer proceeds in a number of phases:</para>
2073
    /// <list type="number">
2074
    /// <item>First, values may be supplied for stylesheet parameters and for the global context item. The
2075
    /// global context item is used when initializing global variables. Unlike earlier transformation APIs,
2076
    /// the global context item is quite independent of the "principal source document".
2077
    /// </item>
2078
    /// <item>The stylesheet may now be repeatedly invoked. Each invocation takes
2079
    /// one of three forms:
2080
    /// <list type="number">
2081
    /// <item>Invocation by applying templates. In this case, the information required is (i) an initial
2082
    /// mode (which defaults to the unnamed mode), (ii) an initial match sequence, which is any
2083
    /// XDM value, which is used as the effective "select" expression of the implicit apply-templates
2084
    /// call, and (iii) optionally, values for the tunnel and non-tunnel parameters defined on the
2085
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
2086
    /// <code>apply-templates</code> call).</item>
2087
    /// <item>Invocation by calling a named template. In this case, the information required is
2088
    /// (i) the name of the initial template (which defaults to "xsl:initial-template"), and
2089
    /// (ii) optionally, values for the tunnel and non-tunnel parameters defined on the
2090
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
2091
    /// <code>call-template</code> instruction).</item>
2092
    /// <item>Invocation by calling a named function. In this case, the information required is
2093
    /// the sequence of arguments to the function call.</item>
2094
    /// </list>
2095
    /// </item>
2096
    /// <item>Whichever invocation method is chosen, the result may either be returned directly, as an arbitrary
2097
    /// XDM value, or it may effectively be wrapped in an XML document. If it is wrapped in an XML document,
2098
    /// that document can be processed in a number of ways, for example it can be materialized as a tree in
2099
    /// memory, it can be serialized as XML or HTML, or it can be subjected to further transformation.</item>
2100
    /// </list>
2101
    /// <para>Once the stylesheet has been invoked (using any of these methods), the values of the global context
2102
    /// item and stylesheet parameters cannot be changed. If it is necessary to run another transformation with
2103
    /// a different context item or different stylesheet parameters, a new <c>Xslt30Transformer</c>
2104
    /// should be created from the original <c>XsltExecutable</c>.</para>
2105
    /// <para> @since 9.6</para> 
2106
    /// </remarks>
2107

    
2108
    [Serializable]
2109
    public class Xslt30Transformer
2110
    {
2111

    
2112

    
2113
        private IResultDocumentHandler resultDocumentHandler;
2114
        private StandardLogger traceFunctionDestination;
2115
        private IMessageListener messageListener;
2116
        private IMessageListener2 messageListener2;
2117
        private JXslt30Transformer transformer;
2118

    
2119
		// internal constructor
2120

    
2121
        internal Xslt30Transformer(JXslt30Transformer transformer)
2122
        {
2123

    
2124
            this.transformer = transformer;
2125
            //this.globalParameterSet = new GlobalParameterSet(globalParameters);
2126
        }
2127

    
2128

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

    
2132
        public XdmItem GlobalContextItem
2133
        {
2134
            set
2135
            {
2136
               transformer.setGlobalContextItem(value == null ? null : XdmItem.FromXdmItemItemToJXdmItem(value));
2137
            }
2138
         
2139
            get { return (XdmItem)XdmItem.Wrap(transformer.getUnderlyingController().getGlobalContextItem()); }
2140

    
2141
        }
2142

    
2143

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

    
2148
        public JXsltController GetUnderlyingController
2149
        {
2150
            get { return transformer.getUnderlyingController(); }
2151
        }
2152

    
2153
        internal JXslt30Transformer GetUnderlyingXslt30Transformer
2154
        {
2155
            get { return transformer; }
2156
        }
2157

    
2158

    
2159
        /// <summary>
2160
		/// Construct a <c>Destination</c> object whose effect is to perform this transformation
2161
		/// on any input that is sent to that <c>Destination</c>: for example, it allows this transformation
2162
		/// to post-process the results of another transformation.
2163
		/// </summary>
2164
		/// <remarks>
2165
        /// <para>This method allows a pipeline of transformations to be created in which
2166
        /// one transformation is used as the destination of another. The transformations
2167
        /// may use streaming, in which case intermediate results will not be materialized
2168
        /// in memory. If a transformation does not use streaming, then its input will
2169
        /// first be assembled in memory as a node tree.</para>
2170
		/// <para>The <c>Destination</c> returned by this method performs <em>sequence normalization</em>
2171
        /// as defined in the serialization specification: that is, the raw result of the transformation
2172
        /// sent to this destination is wrapped into a document node. Any item-separator present in
2173
        /// any serialization parameters is ignored (adjacent atomic values are separated by whitespace). 
2174
        /// This makes the method unsuitable for passing intermediate results other than XML document
2175
        /// nodes.</para>
2176
		/// </remarks>
2177
        /// <param name="finalDestination">supplied final destination</param>
2178
		/// <returns>a <c>Destination</c> which accepts an XML document (typically as a stream
2179
        /// of events) and which transforms this supplied XML document (possibly using streaming)
2180
		/// as defined by the stylesheet from which which this <c>Xslt30Transformer</c>
2181
        /// was generated,
2182
		/// sending the principal result of the transformation to the supplied <c>finalDestination</c>.
2183
		/// The transformation is performed as if by the <see cref="ApplyTemplates(Stream, XmlDestination)"/>
2184
        /// method: that is, by applying templates to the root node of the supplied XML document.
2185
		/// </returns>
2186
        public XmlDestination AsDocumentDestination(XmlDestination finalDestination) {
2187

    
2188
            AbstractDestination localDestination = new AbstractDestination(this, finalDestination);
2189
            return localDestination;
2190
        }
2191

    
2192
		// internal method
2193
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
2194
        {
2195
            JReceiver r = transformer.getDestinationReceiver(transformer.getUnderlyingController(), destination.GetUnderlyingDestination()); 
2196
            return r;
2197
        }
2198

    
2199

    
2200

    
2201
        /// <summary>
2202
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
2203
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
2204
        /// attribute.
2205
        /// </summary>
2206
        /// <remarks>
2207
        /// In the absence of a user-supplied result document handler, the <c>href</c>
2208
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
2209
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
2210
        /// and the resulting absolute URI must identify a writable resource (typically
2211
        /// a file in filestore, using the <c>file:</c> URI scheme).
2212
        /// </remarks>
2213

    
2214
        public IResultDocumentHandler ResultDocumentHandler
2215
        {
2216
            get
2217
            {
2218
                return resultDocumentHandler;
2219
            }
2220
            set
2221
            {
2222
                resultDocumentHandler = value;
2223
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
2224
            }
2225
        }
2226

    
2227
        /// <summary>
2228
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
2229
        /// loaded using the <code>doc()</code>, <code>document()</code>, or <code>collection()</code> functions.
2230
        /// </summary>
2231

    
2232
        public SchemaValidationMode SchemaValidationMode
2233
        {
2234
            get
2235
            {
2236
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
2237
                {
2238
                    case JValidation.STRICT:
2239
                        return SchemaValidationMode.Strict;
2240
                    case JValidation.LAX:
2241
                        return SchemaValidationMode.Lax;
2242
                    case JValidation.STRIP:
2243
                        return SchemaValidationMode.None;
2244
                    case JValidation.PRESERVE:
2245
                        return SchemaValidationMode.Preserve;
2246
                    case JValidation.DEFAULT:
2247
                    default:
2248
                        return SchemaValidationMode.Unspecified;
2249
                }
2250
            }
2251

    
2252

    
2253
            set
2254
            {
2255
                switch (value)
2256
                {
2257
                    case SchemaValidationMode.Strict:
2258
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
2259
                        break;
2260
                    case SchemaValidationMode.Lax:
2261
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
2262
                        break;
2263
                    case SchemaValidationMode.None:
2264
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
2265
                        break;
2266
                    case SchemaValidationMode.Preserve:
2267
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
2268
                        break;
2269
                    case SchemaValidationMode.Unspecified:
2270
                    default:
2271
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
2272
                        break;
2273
                }
2274
            }
2275
        }
2276

    
2277

    
2278

    
2279
        /// <summary> Supply the values of global stylesheet variables and parameters.</summary>
2280
		/// <param name="parameters"> A <c>Dictionary</c> whose keys are QNames identifying global stylesheet parameters,
2281
        /// and whose corresponding values are the values to be assigned to those parameters. If necessary
2282
        /// the supplied values are converted to the declared type of the parameter.
2283
		/// The contents of the supplied <c>Dictionary</c> are copied by this method,
2284
		/// so subsequent changes to the <c>Dictionary</c> have no effect.</param>
2285
        
2286
        public void SetStylesheetParameters(Dictionary<QName, XdmValue> parameters)
2287
        {
2288
            try
2289
            {
2290
                JMap map = new java.util.HashMap();
2291
                foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2292
                {
2293
                    QName qname = entry.Key;
2294
                    map.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2295
                }
2296
                transformer.setStylesheetParameters(map);
2297

    
2298
            }
2299
            catch (net.sf.saxon.trans.XPathException e)
2300
            {
2301
                throw new StaticError(e);
2302
            }
2303

    
2304
        }
2305

    
2306

    
2307

    
2308
        /// <summary>Get the base output URI.</summary>
2309
        /// <remarks><para> This returns the value set using the setter method. If no value has been set
2310
        /// explicitly, then the method returns null if called before the transformation, or the computed
2311
        /// default base output URI if called after the transformation.
2312
        /// </para>
2313
        /// <para> The base output URI is used for resolving relative URIs in the <code>href</code> attribute
2314
        /// of the <code>xsl:result-document</code> instruction.</para></remarks>
2315
        /// <returns> The base output URI</returns>
2316

    
2317
        public String BaseOutputURI
2318
        {
2319
            set
2320
            {
2321
                transformer.setBaseOutputURI(value);
2322
            }
2323
            get { return transformer.getBaseOutputURI(); }
2324
        }
2325

    
2326
        /// <summary>
2327
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
2328
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
2329
        /// </summary>
2330

    
2331
        public XmlResolver InputXmlResolver
2332
        {
2333
            get
2334
            {
2335
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
2336
            }
2337
            set
2338
            {
2339
                transformer.setURIResolver(new JDotNetURIResolver(value));
2340
            }
2341
        }
2342

    
2343
        /// <summary>
2344
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time. 
2345
        /// </summary>
2346
        /// <remarks>By default they are disabled at compile time. If assertions are enabled at compile time, then by
2347
        /// default they will also be enabled at run time; but they can be disabled at run time by
2348
        /// specific request. At compile time, assertions can be enabled for some packages and
2349
        /// disabled for others; at run time, they can only be enabled or disabled globally.</remarks>
2350
        /// <returns>true if assertions are enabled at run time</returns>
2351
        /// <remarks>Since 9.7</remarks>
2352
 
2353
        public bool AssertionsEnabled
2354
        {
2355
            get
2356
            {
2357
                return transformer.isAssertionsEnabled();
2358
            }
2359
        }
2360

    
2361

    
2362
        /// <summary>
2363
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time.
2364
        /// This property name has been misspelt, use <c>AssertionsEnabled</c> instead.
2365
        /// </summary>
2366
        [Obsolete("This property has been replaced by AssertionsEnabled.")]
2367
        public bool ssAssertionsEnabled
2368
        {
2369
            get
2370
            {
2371
                return transformer.isAssertionsEnabled();
2372
            }
2373
        }
2374

    
2375

    
2376
        /// <summary>
2377
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2378
		/// </summary>
2379
		/// <remarks> 
2380
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2381
        /// the processor will then invoke the listener once for each message generated during
2382
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2383
        /// representing a document node.</para>
2384
        /// <para>If no message listener is supplied by the caller, message information will be written to
2385
        /// the standard error stream.</para>
2386
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2387
        /// on the message object will usually generate an acceptable representation of the
2388
        /// message.</para>
2389
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2390
        /// the message is first notified using this interface, and then an exception is thrown
2391
        /// which terminates the transformation.</para>
2392
        /// </remarks>
2393

    
2394
        public IMessageListener MessageListener
2395
        {
2396
            set
2397
            {
2398
                messageListener = value;
2399
                transformer.setMessageListener(new MessageListenerProxy(value));
2400
            }
2401
            get
2402
            {
2403
                return messageListener;
2404
            }
2405
        }
2406

    
2407

    
2408

    
2409
        /// <summary>
2410
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2411
        /// </summary>
2412
        /// <remarks> 
2413
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2414
        /// the processor will then invoke the listener once for each message generated during
2415
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2416
        /// representing a document node.</para>
2417
        /// <para>If no message listener is supplied by the caller, message information will be written to
2418
        /// the standard error stream.</para>
2419
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2420
        /// on the message object will usually generate an acceptable representation of the
2421
        /// message.</para>
2422
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2423
        /// the message is first notified using this interface, and then an exception is thrown
2424
        /// which terminates the transformation.</para>
2425
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
2426
        /// in allowing the error code supplied to xsl:message to be notified</para>
2427
        /// </remarks>
2428

    
2429
        public IMessageListener2 MessageListener2
2430
        {
2431
            set
2432
            {
2433
                messageListener2 = value;
2434
                transformer.setMessageListener(new MessageListenerProxy2(value));
2435
            }
2436
            get
2437
            {
2438
                return messageListener2;
2439
            }
2440
        }
2441

    
2442
        /// <summary>
2443
        /// Destination for output of messages using the <c>trace()</c> function. 
2444
        /// </summary>
2445
		/// <remarks>
2446
		/// <para>If no message listener is supplied by the caller, message information will be written to
2447
		/// the standard error stream.</para>
2448
        /// <para>The supplied destination is ignored if a <code>TraceListener</code> is in use.</para>
2449
        /// </remarks>
2450

    
2451
        public StandardLogger TraceFunctionDestination
2452
        {
2453
            set
2454
            {
2455
                traceFunctionDestination = value;
2456
                transformer.setTraceFunctionDestination(value);
2457
            }
2458
            get
2459
            {
2460
                return traceFunctionDestination;
2461
            }
2462
        }
2463

    
2464

    
2465
        /// <summary>Set parameters to be passed to the initial template. These are used
2466
        /// whether the transformation is invoked by applying templates to an initial source item,
2467
        /// or by invoking a named template. The parameters in question are the <c>xsl:param</c> elements
2468
        /// appearing as children of the <c>xsl:template</c> element.
2469
		/// </summary>
2470
        /// <remarks>
2471
        /// <para>The parameters are supplied in the form of a map; the key is a <c>QName</c> which must
2472
        /// match the name of the parameter; the associated value is an <c>XdmValue</c> containing the
2473
        /// value to be used for the parameter. If the initial template defines any required
2474
        /// parameters, the map must include a corresponding value. If the initial template defines
2475
        /// any parameters that are not present in the map, the default value is used. If the map
2476
        /// contains any parameters that are not defined in the initial template, these values
2477
        /// are silently ignored.</para>
2478
        /// <para>The supplied values are converted to the required type using the function conversion
2479
        /// rules. If conversion is not possible, a run-time error occurs (not now, but later, when
2480
        /// the transformation is actually run).</para>
2481
        /// <para>The <code>Xslt30Transformer</code> retains a reference to the supplied map, so parameters can be added or
2482
        /// changed until the point where the transformation is run.</para>
2483
        /// <para>The XSLT 3.0 specification makes provision for supplying parameters to the initial
2484
        /// template, as well as global stylesheet parameters. Although there is no similar provision
2485
        /// in the XSLT 1.0 or 2.0 specifications, this method works for all stylesheets, regardless whether
2486
        /// XSLT 3.0 is enabled or not.</para></remarks>
2487

    
2488
        /// <param name="parameters"> The parameters to be used for the initial template</param>
2489
        /// <param name="tunnel"> true if these values are to be used for setting tunnel parameters;
2490
        /// false if they are to be used for non-tunnel parameters</param>
2491
        
2492
        public void SetInitialTemplateParameters(Dictionary<QName, XdmValue> parameters, bool tunnel)
2493
        {
2494

    
2495
            JMap templateParameters = new java.util.HashMap();
2496
            foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2497
            {
2498
                QName qname = entry.Key;
2499
                templateParameters.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2500
            }
2501

    
2502
            transformer.setInitialTemplateParameters(templateParameters, tunnel);
2503

    
2504

    
2505
        }
2506

    
2507

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

    
2513
        public QName InitialMode
2514
        {
2515

    
2516
            set
2517
            {
2518
                try
2519
                {
2520
                    transformer.setInitialMode(value == null ? null : value.UnderlyingQName());
2521
                }
2522
                catch (net.sf.saxon.trans.XPathException e)
2523
                {
2524
                    throw new DynamicError(e);
2525
                }
2526
            }
2527
            get
2528
            {
2529
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
2530
                if (mode == null)
2531
                    return null;
2532
                else
2533
                {
2534
                    return new QName(mode);
2535
                }
2536
            }
2537

    
2538

    
2539
        }
2540

    
2541

    
2542
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2543
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2544
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2545
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2546
        /// </summary>
2547
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2548
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2549
        /// <param name="destination">The destination of the result document produced by wrapping the result 
2550
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2551
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2552
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2553

    
2554
        public void ApplyTemplates(Stream input, XmlDestination destination)
2555
        {
2556
            try
2557
            {
2558
                JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2559
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2560
            
2561
            }
2562
            catch (JSaxonApiException exp)
2563
            {
2564
                throw new DynamicError(exp);
2565
            }
2566

    
2567
        }
2568

    
2569

    
2570
		/// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2571
		/// using the supplied base URI,
2572
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2573
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2574
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2575
		/// </summary>
2576
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2577
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2578
		/// <param name="baseUri">Base URI used for the input document</param>
2579
		/// <param name="destination">The destination of the result document produced by wrapping the result 
2580
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2581
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2582
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2583

    
2584
        public void ApplyTemplates(Stream input, Uri baseUri, XmlDestination destination)
2585
        {
2586
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2587
            try
2588
            {
2589
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2590
            }
2591
            catch (JSaxonApiException exp)
2592
            {
2593
                throw new DynamicError(exp.getMessage());
2594
            }
2595

    
2596
        }
2597

    
2598

    
2599
        /// <summary>
2600
        /// Invoke the stylesheet by applying templates to a supplied source document, sending the results
2601
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2602
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2603
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2604
        /// </summary>
2605
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2606
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2607
        /// <param name="destination">The destination of the principal result of the transformation.
2608
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2609
        /// parameters set in the serializer are combined with those defined in the stylesheet
2610
        /// (the parameters set in the serializer take precedence).</param>
2611
        /// <remarks>since 9.9.1.5</remarks>
2612
        public void Transform(Stream input, XmlDestination destination) {
2613
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2614

    
2615
            try
2616
            {
2617
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2618
            }
2619
            catch (JSaxonApiException exp)
2620
            {
2621
                throw new DynamicError(exp.getMessage());
2622
            }
2623

    
2624
        }
2625

    
2626
        /// <summary>
2627
        /// Invoke the stylesheet by applying templates to a supplied Source document,  
2628
        /// using the supplied base URI, sending the results
2629
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2630
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2631
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2632
        /// </summary>
2633
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2634
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2635
        /// <param name="baseUri">Base URI used for the input document</param>
2636
        /// <param name="destination">The destination of the principal result of the transformation.
2637
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2638
        /// parameters set in the serializer are combined with those defined in the stylesheet
2639
        /// (the parameters set in the serializer take precedence).</param>
2640
        /// <remarks>since 9.9.1.5</remarks>
2641
        public void Transform(Stream input, Uri baseUri, XmlDestination destination)
2642
        {
2643
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2644
            try
2645
            {
2646
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2647
            }
2648
            catch (JSaxonApiException exp)
2649
            {
2650
                throw new DynamicError(exp.getMessage());
2651
            }
2652

    
2653
        }
2654

    
2655

    
2656

    
2657

    
2658
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2659
		/// using the supplied base URI,
2660
		/// returning the raw results as an <c>XdmValue</c>. The 
2661
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2662
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2663
		/// </summary>
2664
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2665
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2666
		/// <param name="baseUri">Base URI</param>
2667
		/// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2668
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2669
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2670

    
2671
        public XdmValue ApplyTemplates(Stream input, Uri baseUri)
2672
        {
2673
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2674

    
2675
            try
2676
            {
2677
                net.sf.saxon.s9api.XdmValue value = transformer.applyTemplates(streamSource);
2678
                return XdmValue.Wrap(value.getUnderlyingValue());
2679

    
2680
            }
2681
            catch (JSaxonApiException exp)
2682
            {
2683
                throw new DynamicError(exp);
2684
            }
2685

    
2686
        }
2687

    
2688

    
2689
        /// <summary>
2690
        /// Invoke the stylesheet by applying templates to a supplied input sequence, sending the results (wrapped
2691
		/// in a document node) to a given <c>Destination</c>. The invocation uses any initial mode set using 
2692
		/// <see cref="InitialMode"/>, and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2693
        /// </summary>
2694
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2695
        /// attribute of <code>xsl:apply-templates</code>)</param>
2696
        /// <param name="destination">The destination of the result document produced by wrapping the result of the apply-templates
2697
        /// call in a document node.  If the destination is a <see cref="Serializer"/>, then the serialization
2698
        /// parameters set in the serializer are combined with those defined in the stylesheet
2699
        /// (the parameters set in the serializer take precedence).</param>
2700

    
2701
        public void ApplyTemplates(XdmValue selection, XmlDestination destination)
2702
        {
2703
            
2704
            try
2705
            {
2706
                transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value), destination.GetUnderlyingDestination());
2707
            }
2708
            catch (JSaxonApiException ex)
2709
            {
2710

    
2711
                throw new DynamicError(ex);
2712
            }
2713

    
2714
        }
2715

    
2716

    
2717

    
2718
        /// <summary>
2719
        /// Invoke the stylesheet by applying templates to a supplied input sequence, returning the raw results
2720
        /// as an <see cref="XdmValue"/>. The invocation uses any initial mode set using <see cref="InitialMode"/>,
2721
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2722
        /// </summary>
2723
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2724
        /// attribute of <code>xsl:apply-templates</code>)</param>
2725
        /// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2726
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2727
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2728

    
2729
        public XdmValue ApplyTemplates(XdmValue selection)
2730
        {
2731
           
2732
            try
2733
            {
2734
                return XdmValue.Wrap(transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value)).getUnderlyingValue());
2735
               
2736
            }
2737
            catch (JSaxonApiException ex)
2738
            {
2739

    
2740
                throw new DynamicError(ex);
2741
            }
2742

    
2743
        }
2744

    
2745

    
2746
        /// <summary> Invoke a transformation by calling a named template. The results of calling
2747
        /// the template are wrapped in a document node, which is then sent to the specified
2748
        /// destination. If <see cref="SetInitialTemplateParameters"/> has been
2749
        /// called, then the parameters supplied are made available to the called template (no error
2750
        /// occurs if parameters are supplied that are not used).</summary> 
2751
        /// <param name="templateName"> The name of the initial template. This must match the name of a
2752
        /// public named template in the stylesheet. If the value is null,
2753
        /// the QName <code>xsl:initial-template</code> is used.</param>
2754
        /// <param name="destination"> The destination of the result document produced by wrapping the result 
2755
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2756
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2757
        /// (the parameters set in the serializer take precedence).</param> 
2758

    
2759
        public void CallTemplate(QName templateName, XmlDestination destination)
2760
        {
2761
           
2762
            if (templateName == null)
2763
            {
2764
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2765
            }
2766

    
2767
            try
2768
            {
2769
                transformer.callTemplate(templateName.UnderlyingQName(), destination.GetUnderlyingDestination());
2770
               
2771
            }
2772
            catch (JSaxonApiException exp)
2773
            {
2774
                throw new DynamicError(exp);
2775
            }
2776
        }
2777

    
2778

    
2779

    
2780
        /// <summary>
2781
        /// Invoke a transformation by calling a named template. The results of calling
2782
        /// the template are returned as a raw value, without wrapping in a document nnode
2783
        /// or serializing.
2784
        /// </summary>
2785
        /// <param name="templateName">The name of the initial template. This must match the name of a
2786
        /// public named template in the stylesheet. If the value is null, the QName <c>xsl:initial-template</c> is used.</param>
2787
        /// <returns>the raw results of the called template, without wrapping in a document node or serialization.</returns>
2788

    
2789
        public XdmValue CallTemplate(QName templateName)
2790
        {
2791
            if (templateName == null)
2792
            {
2793
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2794
            }
2795

    
2796
            try
2797
            {
2798
                return XdmValue.Wrap(transformer.callTemplate(templateName.UnderlyingQName()).getUnderlyingValue());
2799
            }
2800
            catch (JSaxonApiException exp)
2801
            {
2802
                throw new DynamicError(exp);
2803
            }
2804
        }
2805

    
2806

    
2807
        /// <summary> Call a public user-defined function in the stylesheet. </summary>
2808
        /// <param name="function"> The name of the function to be called</param>
2809
        /// <param name="arguments">  The values of the arguments to be supplied to the function. These
2810
        /// will be converted if necessary to the type as defined in the function signature, using
2811
        /// the function conversion rules.</param>
2812
        /// <returns> the result of calling the function. This is the raw result, without wrapping in a document
2813
        /// node and without serialization.</returns>
2814

    
2815
        public XdmValue CallFunction(QName function, XdmValue[] arguments)
2816
        {
2817
            try
2818
            {
2819
                int len = arguments.Length;
2820
                net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2821

    
2822
                for (int i=0; i<len; i++) {
2823
                    values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2824

    
2825
                }
2826

    
2827
                return XdmValue.Wrap(transformer.callFunction(function.UnderlyingQName(), values).getUnderlyingValue());
2828

    
2829
            }
2830
            catch (JSaxonApiException ex)
2831
            {
2832
                throw new DynamicError(ex);
2833

    
2834
            }
2835

    
2836
        }
2837

    
2838

    
2839

    
2840
        /// <summary>Call a public user-defined function in the stylesheet, wrapping the result in an XML document, 
2841
		/// and sending this document to a specified destination</summary>    
2842
        /// <param name="function"> The name of the function to be called</param>
2843
        /// <param name="arguments"> The values of the arguments to be supplied to the function. These
2844
        /// will be converted if necessary to the type as defined in the function signature, using
2845
        /// the function conversion rules.</param>
2846
        /// <param name="destination"> The destination of the result document produced by wrapping the 
2847
		/// result of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2848
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2849
        /// (the parameters set in the serializer take precedence).</param>
2850

    
2851
        public void CallFunction(QName function, XdmValue[] arguments, XmlDestination destination)
2852
        {
2853

    
2854
            int len = arguments.Length;
2855
            net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2856

    
2857
            for (int i = 0; i < len; i++)
2858
            {
2859
                values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2860

    
2861
            }
2862
            try
2863
            {
2864
                transformer.callFunction(function.UnderlyingQName(), values, destination.GetUnderlyingDestination());
2865

    
2866
            }
2867
            catch (JSaxonApiException ex) {
2868
                throw new DynamicError(ex);
2869
            }
2870
        }
2871

    
2872

    
2873
    }
2874

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

    
2878
    [Serializable]
2879
    public class XsltPackage
2880
    {
2881
        private JXsltPackage package;
2882
        private Processor processor;
2883
		// internal constructor: Initializes a new instance of the <see cref="Saxon.Api.XsltPackage"/> class.
2884
        internal XsltPackage(Processor p, JXsltPackage pp)
2885
        {
2886
            this.package = pp;
2887
            this.processor = p;
2888

    
2889
        }
2890

    
2891
        /// <summary>
2892
        /// Get the Processor from which this <c>XsltPackage</c> was constructed
2893
        /// </summary>
2894

    
2895
        public Processor Processor
2896
        {
2897
            get { return processor; }
2898
        }
2899

    
2900

    
2901
        /// <summary>
2902
        /// Get the name of the package (the URI appearing as the value of <code>xsl:package/@name</code>)
2903
        /// </summary>
2904
        /// <returns>The package name</returns>
2905

    
2906
        public String PackageName
2907
        {
2908
            get { return package.getName(); }
2909
        }
2910

    
2911

    
2912
        /// <summary>Get the version number of the package (the value of the attribute 
2913
		/// <code>xsl:package/@package-version</code></summary>
2914
        /// <returns>The package version number</returns>
2915

    
2916
        public String Version
2917
        {
2918
            get { return package.getVersion(); }
2919
        }
2920

    
2921

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

    
2927
        public XsltExecutable Link()
2928
        {
2929
            try
2930
            {
2931
                JXsltExecutable jexecutable = package.link();
2932
                XsltExecutable executable = new XsltExecutable(jexecutable);
2933
                executable.InternalProcessor = processor;
2934
                return executable;
2935
            }
2936
            catch (net.sf.saxon.trans.XPathException e)
2937
            {
2938
                throw new StaticError(e);
2939
            }
2940
        }
2941

    
2942
        /// <summary>Save this compiled package to filestore.</summary>
2943
        /// <param name="stream"> the stream to which the compiled package should be saved</param>
2944

    
2945
        public void Save(Stream stream)
2946
        {
2947
            JDotNetOutputStream outputStream = new JDotNetOutputStream(stream);
2948
            JExpressionPresenter outp = new JExpressionPresenter(package.getProcessor().getUnderlyingConfiguration(), new javax.xml.transform.stream.StreamResult(outputStream), true);
2949
            try
2950
            {
2951
                package.getUnderlyingPreparedPackage().export(outp);
2952
            }
2953
            catch (net.sf.saxon.trans.XPathException e)
2954
            {
2955
                throw new StaticError(e);
2956
            }
2957
        }
2958

    
2959

    
2960
        /// <summary>Escape-hatch interface to the underlying implementation class.</summary>
2961
		/// <returns>the underlying <c>StylesheetPackage</c>. The interface to <c>StylesheetPackage</c>
2962
        /// is not a stable part of the s9api API definition.</returns>
2963

    
2964
        public JStylesheetPackage getUnderlyingPreparedPackage()
2965
        {
2966
            return package.getUnderlyingPreparedPackage();
2967
        }
2968

    
2969
        internal JXsltPackage GetUnderlyingXsltPackage() {
2970
            return package;
2971
        }
2972
        
2973
    }
2974

    
2975

    
2976
}
2977

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