Project

Profile

Help

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

he / src / samples / cs / ExamplesHE.cs @ d1236b02

1
using System;
2
using System.IO;
3
using System.Collections;
4
using System.Xml;
5
using System.Net;
6
using Saxon.Api;
7
using System.Collections.Generic;
8

    
9
namespace SaxonHE
10
{
11
    class ExamplesHE
12
    {
13
        /// <summary>
14
        /// Run Saxon XSLT and XQuery sample applications in Saxon Home Edition on .NET
15
        /// </summary>
16
        /// <param name="argv">
17
        /// <para>Options:</para>
18
        /// <list>
19
        /// <item>-test:testname  run a specific test</item>
20
        /// <item>-dir:samplesdir directory containing the sample data files (default %SAXON_HOME%/samples)</item>
21
        /// <item>-ask:yes|no     indicates whether to prompt for confirmation after each test (default yes)</item>
22
        /// </list>
23
        /// </param>
24

    
25

    
26
        public static void Main(String[] argv)
27
        {
28

    
29
            Example[] examples = {
30
                new XPathSimple(),
31
                new XPathSimple2(),
32
                new XPathVariables(),
33
                new XPathUndeclaredVariables(),
34
                new XPathWithStaticError(),
35
                new XPathWithDynamicError(),
36
                new XsltSimple1(),
37
                new XsltSimple2(),
38
                new XsltSimple3(),
39
                new XsltStripSpace(),
40
                new XsltReuseExecutable(),
41
                new XsltReuseTransformer(),
42
                new XsltFilterChain(),
43
                new XsltDomToDom(),
44
                new XsltXdmToXdm(),
45
                new XsltXdmElementToXdm(),
46
                new XsltUsingSourceResolver(),
47
                new XsltSettingOutputProperties(),
48
                new XsltDisplayingErrors(),
49
                new XsltCapturingErrors(),
50
                new XsltCapturingMessages(),
51
                new XsltProcessingInstruction(),
52
                new XsltMultipleOutput(),
53
                new XsltUsingResultHandler(),
54
                new XsltUsingIdFunction(),
55
                new XsltUsingRegisteredCollection(),
56
                new XsltUsingDirectoryCollection(),
57
                new XsltIntegratedExtension(),
58
                new XsltSimpleExtension(),
59
                new XQueryToStream(),
60
                new XQueryToAtomicValue(),
61
                new XQueryToSequence(),
62
                new XQueryToDom(),
63
                new XQueryToXdm(),
64
                new XQueryCallFunction(),
65
                new XQueryFromXmlReader(),
66
                new XQueryToSerializedSequence(),
67
                new XQueryUsingParameter(),
68
                new XQueryMultiModule()
69
            };
70

    
71
            Boolean ask = true;
72
            String test = "all";
73

    
74
            String samplesPath = null;
75
            Uri samplesDir;
76

    
77
            foreach (String s in argv)
78
            {
79
                if (s.StartsWith("-test:"))
80
                {
81
                    test = s.Substring(6);
82
                }
83
                else if (s.StartsWith("-dir:"))
84
                {
85
                    samplesPath = s.Substring(5);
86
                }
87
                else if (s == "-ask:yes")
88
                {
89
                    // no action
90
                }
91
                else if (s == "-ask:no")
92
                {
93
                    ask = false;
94
                }
95
                else if (s == "-?")
96
                {
97
                    Console.WriteLine("ExamplesHE -dir:samples -test:testname -ask:yes|no");
98
                }
99
                else
100
                {
101
                    Console.WriteLine("Unrecognized Argument: " + s);
102
                    return;
103
                }
104
            }
105
            if (samplesPath != null)
106
            {
107
                if (samplesPath.StartsWith("file:///"))
108
                {
109
                    samplesPath = samplesPath.Substring(8);
110
                }
111
                else if (samplesPath.StartsWith("file:/"))
112
                {
113
                    samplesPath = samplesPath.Substring(6);
114
                }
115

    
116
            }
117
            else
118
            {
119
                String home = Environment.GetEnvironmentVariable("SAXON_HOME");
120
                if (home == null)
121
                {
122
                    Console.WriteLine("No input directory supplied, and SAXON_HOME is not set");
123
                    return;
124
                }
125
                else
126
                {
127
                    if (!(home.EndsWith("/") || home.EndsWith("\\")))
128
                    {
129
                        home = home + "/";
130
                    }
131
                    samplesPath = home + "samples/";
132
                }
133
            }
134

    
135
            if (!(samplesPath.EndsWith("/") || samplesPath.EndsWith("\\")))
136
            {
137
                samplesPath = samplesPath + "/";
138
            }
139

    
140
            if (!File.Exists(samplesPath + "data/books.xml"))
141
            {
142
                Console.WriteLine("Supplied samples directory " + samplesPath + " does not contain the Saxon sample data files");
143
                return;
144
            }
145

    
146
            try
147
            {
148
                samplesDir = new Uri(samplesPath);
149
            }
150
            catch
151
            {
152
                Console.WriteLine("Invalid URI for samples directory: " + samplesPath);
153
                return;
154
            }
155

    
156
            Boolean found = false;
157
            foreach (Example ex in examples)
158
            {
159
                if (test == "all" || test == ex.testName)
160
                {
161
                    Console.WriteLine("\n\n===== " + ex.testName + " =======\n");
162
                    found = true;
163
                    try
164
                    {
165
                        ex.run(samplesDir);
166
                    }
167
                    catch (Saxon.Api.StaticError se)
168
                    {
169
                        Console.WriteLine("Test failed with static error " + (se.ErrorCode != null ? se.ErrorCode.LocalName : "") + ": " + se.Message);
170
                    }
171
                    catch (Saxon.Api.DynamicError de)
172
                    {
173
                        Console.WriteLine("Test failed with dynamic error " + (de.ErrorCode != null ? de.ErrorCode.LocalName : "") + ": " + de.Message);
174
                    }
175
                    catch (Exception exc)
176
                    {
177
                        Console.WriteLine("Test failed unexpectedly (" + exc.GetType() + "): " + exc.Message);
178
                        Console.WriteLine(exc.StackTrace);
179
                    }
180
                    if (ask)
181
                    {
182
                        Console.WriteLine("\n\nContinue? - type (Y(es)/N(o)/A(ll))");
183
                        String answer = Console.ReadLine();
184
                        if (answer == "N" || answer == "n")
185
                        {
186
                            break;
187
                        }
188
                        else if (answer == "A" || answer == "a")
189
                        {
190
                            ask = false;
191
                        }
192
                    }
193
                }
194
            }
195
            if (!found)
196
            {
197
                Console.WriteLine("Please supply a valid test name, or 'all' ('" + test + "' is invalid)");
198
            }
199
            Console.WriteLine("\n==== done! ====");
200
        }
201
    }
202

    
203
    ///<summary>
204
    /// Each of the example programs is implemented as a subclass of the abstract class Example
205
    ///</summary> 
206

    
207

    
208
    public abstract class Example
209
    {
210
        /// <summary>
211
        /// Read-only property: the name of the test example
212
        /// </summary>
213
        public abstract String testName { get; }
214
        /// <summary>
215
        /// Entry point for running the example
216
        /// </summary>
217
        public abstract void run(Uri samplesDir);
218
    }
219

    
220
    /// <summary>
221
    /// Evaluate an XPath expression selecting from a source document supplied as a URI
222
    /// </summary>
223

    
224
    public class XPathSimple : Example
225
    {
226

    
227
        public override String testName
228
        {
229
            get { return "XPathSimple"; }
230
        }
231

    
232
        public override void run(Uri samplesDir)
233
        {
234
            // Create a Processor instance.
235
            Processor processor = new Processor();
236

    
237
            // Load the source document
238
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
239

    
240
            // Create an XPath compiler
241
            XPathCompiler xpath = processor.NewXPathCompiler();
242

    
243
            // Enable caching, so each expression is only compiled once
244
            xpath.Caching = true;
245

    
246
            // Compile and evaluate some XPath expressions
247
            foreach (XdmItem item in xpath.Evaluate("//ITEM", input))
248
            {
249
                Console.WriteLine("TITLE: " + xpath.EvaluateSingle("string(TITLE)", item));
250
                Console.WriteLine("PRICE: " + xpath.EvaluateSingle("string(PRICE)", item));
251
            }
252
        }
253
    }
254

    
255
    /// <summary>
256
    /// Evaluate an XPath expression against a source document, returning its effective boolean value
257
    /// </summary>
258

    
259
    public class XPathSimple2 : Example
260
    {
261

    
262
        public override String testName
263
        {
264
            get { return "XPathSimple2"; }
265
        }
266

    
267
        public override void run(Uri samplesDir)
268
        {
269
            // Create a Processor instance.
270
            Processor processor = new Processor();
271

    
272
            // Load the source document
273
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
274

    
275
            // Create an XPath compiler
276
            XPathCompiler xpath = processor.NewXPathCompiler();
277

    
278
            // Enable caching, so each expression is only compiled once
279
            xpath.Caching = true;
280
            
281
            // Compile and evaluate an XPath expression
282
            XPathSelector selector = xpath.Compile("//ITEM").Load();
283
            selector.ContextItem = input;
284
            Console.WriteLine(selector.EffectiveBooleanValue());
285

    
286
        }
287
    }
288

    
289
    /// <summary>
290
    /// Evaluate an XPath expression using variables (and no source document)
291
    /// </summary>
292

    
293
    public class XPathVariables : Example
294
    {
295

    
296
        public override String testName
297
        {
298
            get { return "XPathVariables"; }
299
        }
300

    
301
        public override void run(Uri samplesDir)
302
        {
303
            // Create a Processor instance.
304
            Processor processor = new Processor();
305

    
306
            // Create the XPath expression.
307
            XPathCompiler compiler = processor.NewXPathCompiler();
308
            compiler.DeclareVariable(new QName("", "a"));
309
            compiler.DeclareVariable(new QName("", "b"));
310
            XPathSelector selector = compiler.Compile("$a + $b").Load();
311

    
312
            // Set the values of the variables
313
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(2));
314
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue(3));
315

    
316
            // Evaluate the XPath expression
317
            Console.WriteLine(selector.EvaluateSingle().ToString());
318
        }
319
    }
320

    
321
    /// <summary>
322
    /// Evaluate an XPath expression using variables without explicit declaration
323
    /// </summary>
324

    
325
    public class XPathUndeclaredVariables : Example
326
    {
327

    
328
        public override String testName
329
        {
330
            get { return "XPathUndeclaredVariables"; }
331
        }
332

    
333
        public override void run(Uri samplesDir)
334
        {
335
            // Create a Processor instance.
336
            Processor processor = new Processor();
337

    
338
            // Create the XPath expression.
339
            XPathCompiler compiler = processor.NewXPathCompiler();
340
            compiler.AllowUndeclaredVariables = true;
341
            XPathExecutable expression = compiler.Compile("$a + $b");
342
            XPathSelector selector = expression.Load();
343

    
344
            // Set the values of the variables
345
            IEnumerator<QName> vars = expression.EnumerateExternalVariables2();
346
            while (vars.MoveNext())
347
            {
348
                selector.SetVariable((QName)vars.Current, new XdmAtomicValue(10));
349
            }
350

    
351
            // Evaluate the XPath expression
352
            Console.WriteLine(selector.EvaluateSingle().ToString());
353
        }
354
    }
355

    
356
    /// <summary>
357
    /// Evaluate an XPath expression throwing a static error
358
    /// </summary>
359

    
360
    public class XPathWithStaticError : Example
361
    {
362

    
363
        public override String testName
364
        {
365
            get { return "XPathWithStaticError"; }
366
        }
367

    
368
        public override void run(Uri samplesDir)
369
        {
370
            // Create a Processor instance.
371
            Processor processor = new Processor();
372

    
373
            // Create the XPath expression.
374
            XPathCompiler compiler = processor.NewXPathCompiler();
375
            compiler.AllowUndeclaredVariables = true;
376
            XPathExecutable expression = compiler.Compile("1 + unknown()");
377
            XPathSelector selector = expression.Load();
378

    
379
            // Evaluate the XPath expression
380
            Console.WriteLine(selector.EvaluateSingle().ToString());
381
        }
382
    }
383

    
384
    /// <summary>
385
    /// Evaluate an XPath expression throwing a dynamic error
386
    /// </summary>
387

    
388
    public class XPathWithDynamicError : Example
389
    {
390

    
391
        public override String testName
392
        {
393
            get { return "XPathWithDynamicError"; }
394
        }
395

    
396
        public override void run(Uri samplesDir)
397
        {
398
            // Create a Processor instance.
399
            Processor processor = new Processor();
400

    
401
            // Create the XPath expression.
402
            XPathCompiler compiler = processor.NewXPathCompiler();
403
            compiler.AllowUndeclaredVariables = true;
404
            XPathExecutable expression = compiler.Compile("$a gt $b");
405
            XPathSelector selector = expression.Load();
406

    
407
            // Set the values of the variables
408
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(10));
409
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue("Paris"));
410

    
411
            // Evaluate the XPath expression
412
            Console.WriteLine(selector.EvaluateSingle().ToString());
413
        }
414
    }
415

    
416
    /// <summary>
417
    /// XSLT 2.0 transformation with source document and stylesheet supplied as URIs
418
    /// </summary>
419

    
420
    public class XsltSimple1 : Example
421
    {
422

    
423
        public override String testName
424
        {
425
            get { return "XsltSimple1"; }
426
        }
427

    
428
        public override void run(Uri samplesDir)
429
        {
430
            // Create a Processor instance.
431
            Processor processor = new Processor();
432

    
433
            // Load the source document
434
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
435

    
436
            // Create a transformer for the stylesheet.
437
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/books.xsl")).Load30();
438

    
439
            // Set the root node of the source document to be the global context item
440
            transformer.GlobalContextItem = input;
441

    
442
            // Create a serializer, with output to the standard output stream
443
            Serializer serializer = processor.NewSerializer();
444
            serializer.SetOutputWriter(Console.Out);
445

    
446
            // Transform the source XML and serialize the result document
447
            transformer.ApplyTemplates(input, serializer);
448
        }
449
    }
450

    
451
    /// <summary>
452
    /// Run a transformation, sending the serialized output to a file
453
    /// </summary>
454

    
455
    public class XsltSimple2 : Example
456
    {
457

    
458
        public override String testName
459
        {
460
            get { return "XsltSimple2"; }
461
        }
462

    
463
        public override void run(Uri samplesDir)
464
        {
465
            // Create a Processor instance.
466
            Processor processor = new Processor();
467

    
468
            // Load the source document
469
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
470

    
471
            // Create a transformer for the stylesheet.
472
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/identity.xsl")).Load30();
473

    
474
            // Create a serializer
475
            String outfile = "OutputFromXsltSimple2.xml";
476
            Serializer serializer = processor.NewSerializer();
477
            serializer.SetOutputStream(new FileStream(outfile, FileMode.Create, FileAccess.Write));
478

    
479
            // Transform the source XML and serialize the result to the output file.
480
            transformer.ApplyTemplates(input, serializer);
481

    
482
            Console.WriteLine("\nOutput written to " + outfile + "\n");
483
        }
484
    }
485

    
486
    /// <summary>
487
    /// XSLT 2.0 transformation with source document and stylesheet supplied as files
488
    /// </summary>
489

    
490
    public class XsltSimple3 : Example
491
    {
492

    
493
        public override String testName
494
        {
495
            get { return "XsltSimple3"; }
496
        }
497

    
498
        public override void run(Uri samplesDir)
499
        {
500
            if (samplesDir.Scheme != Uri.UriSchemeFile)
501
            {
502
                Console.WriteLine("Supplied URI must be a file directory");
503
            }
504
            String dir = samplesDir.AbsolutePath;
505
            String sourceFile = dir + "data/books.xml";
506
            String styleFile = dir + "styles/books.xsl";
507

    
508
            // Create a Processor instance.
509
            Processor processor = new Processor();
510

    
511
            // Load the source document
512
            DocumentBuilder builder = processor.NewDocumentBuilder();
513
            builder.BaseUri = new Uri(samplesDir, "data/books.xml");
514

    
515
            XdmNode input = builder.Build(File.OpenRead(sourceFile));
516

    
517
            // Create a transformer for the stylesheet.
518
            XsltCompiler compiler = processor.NewXsltCompiler();
519
            compiler.BaseUri = new Uri(samplesDir, "styles/books.xsl");
520
            Xslt30Transformer transformer = compiler.Compile(File.OpenRead(styleFile)).Load30();
521

    
522
            // Set the root node of the source document to be the global context item
523
            transformer.GlobalContextItem = input;
524

    
525
            // Create a serializer, with output to the standard output stream
526
            Serializer serializer = processor.NewSerializer();
527
            serializer.SetOutputWriter(Console.Out);
528

    
529
            // Transform the source XML and serialize the result document
530
            transformer.ApplyTemplates(input, serializer);
531
        }
532
    }
533

    
534

    
535
    /// <summary>
536
    /// XSLT 2.0 transformation showing stripping of whitespace controlled by the stylesheet
537
    /// </summary>
538

    
539
    public class XsltStripSpace : Example
540
    {
541

    
542
        public override String testName
543
        {
544
            get { return "XsltStripSpace"; }
545
        }
546

    
547
        public override void run(Uri samplesDir)
548
        {
549
            Processor processor = new Processor();
550

    
551
            // Load the source document
552
            DocumentBuilder builder = processor.NewDocumentBuilder();
553
            builder.BaseUri = samplesDir;
554

    
555
            String doc = "<doc>  <a>  <b>text</b>  </a>  <a/>  </doc>";
556
            MemoryStream ms = new MemoryStream();
557
            StreamWriter tw = new StreamWriter(ms);
558
            tw.Write(doc);
559
            tw.Flush();
560
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
561
            XdmNode input = builder.Build(instr);
562

    
563
            // Create a transformer for the stylesheet.
564
            String stylesheet =
565
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>" +
566
                "<xsl:strip-space elements='*'/>" +
567
                "<xsl:template match='/'>" +
568
                "  <xsl:copy-of select='.'/>" +
569
                "</xsl:template>" +
570
                "</xsl:stylesheet>";
571

    
572
            XsltCompiler compiler = processor.NewXsltCompiler();
573
            compiler.BaseUri = samplesDir;
574
            Xslt30Transformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load30();
575

    
576
            // Create a serializer, with output to the standard output stream
577
            Serializer serializer = processor.NewSerializer();
578
            serializer.SetOutputWriter(Console.Out);
579

    
580
            // Transform the source XML and serialize the result document
581
            transformer.ApplyTemplates(input, serializer);
582
        }
583
    }
584

    
585

    
586
	/// <summary>
587
	/// Run a transformation, compiling the stylesheet once (into an XsltExecutable) and using it to transform two 
588
	/// different source documents
589
	/// </summary>
590

    
591
    public class XsltReuseExecutable : Example
592
    {
593

    
594
        public override String testName
595
        {
596
            get { return "XsltReuseExecutable"; }
597
        }
598

    
599
        public override void run(Uri samplesDir)
600
        {
601
            // Create a Processor instance.
602
            Processor processor = new Processor();
603

    
604
            // Create a compiled stylesheet
605
            XsltExecutable templates = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
606

    
607
            // Note: we could actually use the same Xslt30Transformer in this case.
608
            // But in principle, the two transformations could be done in parallel in separate threads.
609

    
610
            String sourceFile1 = "data/books.xml";
611
            String sourceFile2 = "data/othello.xml";
612

    
613
            // Do the first transformation
614
            Console.WriteLine("\n\n----- transform of " + sourceFile1 + " -----");
615
            Xslt30Transformer transformer1 = templates.Load30();
616
            XdmNode input1 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile1));
617
            transformer1.ApplyTemplates(input1, processor.NewSerializer(Console.Out));     // default destination is Console.Out
618

    
619
            // Do the second transformation
620
            Console.WriteLine("\n\n----- transform of " + sourceFile2 + " -----");
621
            Xslt30Transformer transformer2 = templates.Load30();
622
            XdmNode input2 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile2));
623
            transformer2.ApplyTemplates(input2, processor.NewSerializer(Console.Out));     // default destination is Console.Out
624
        }
625
    }
626

    
627
    /// <summary>
628
    /// Show that the Xslt30Transformer is serially reusable; run a transformation twice using the same stylesheet
629
    /// and the same stylesheet parameters, but with a different input document.
630
    /// </summary>
631

    
632
    public class XsltReuseTransformer : Example
633
    {
634

    
635
        public override String testName
636
        {
637
            get { return "XsltReuseTransformer"; }
638
        }
639

    
640
        public override void run(Uri samplesDir)
641
        {
642
            // Create a Processor instance.
643
            Processor processor = new Processor();
644

    
645
            // Compile the stylesheet
646
            XsltExecutable exec = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
647

    
648
            // Create a transformer 
649
            Xslt30Transformer transformer = exec.Load30();
650
            
651
            // Set the stylesheet parameters
652
            Dictionary<QName, XdmValue> params1 = new Dictionary<QName, XdmValue>();
653
            params1.Add(new QName("", "", "include-attributes"), new XdmAtomicValue(false));
654
            transformer.SetStylesheetParameters(params1);
655

    
656
            // Load the 1st source document, building a tree
657
            XdmNode input1 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
658

    
659
            // Run the transformer once
660
            XdmDestination results = new XdmDestination();
661
            transformer.ApplyTemplates(input1, results);
662
            Console.WriteLine("1: " + results.XdmNode.OuterXml);
663

    
664
            // Load the 2nd source document, building a tree
665
            XdmNode input2 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/more-books.xml"));
666

    
667
            // Run the transformer again
668
            results.Reset();
669
            transformer.ApplyTemplates(input2, results);
670
            Console.WriteLine("2: " + results.XdmNode.OuterXml);
671
        }
672
    }
673

    
674
    /// <summary>
675
    /// Run a sequence of transformations in a pipeline, each one acting as a filter
676
    /// </summary>
677

    
678
    public class XsltFilterChain : Example
679
    {
680

    
681
        public override String testName
682
        {
683
            get { return "XsltFilterChain"; }
684
        }
685

    
686
        public override void run(Uri samplesDir)
687
        {
688
            // Create a Processor instance.
689
            Processor processor = new Processor();
690

    
691
            // Load the source document
692
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
693

    
694
            // Create a compiler
695
            XsltCompiler compiler = processor.NewXsltCompiler();
696

    
697
            // Compile all three stylesheets
698
            Xslt30Transformer transformer1 = compiler.Compile(new Uri(samplesDir, "styles/identity.xsl")).Load30();
699
            Xslt30Transformer transformer2 = compiler.Compile(new Uri(samplesDir, "styles/books.xsl")).Load30();
700
            Xslt30Transformer transformer3 = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
701

    
702
            // Now run them in series
703
            XdmDestination results1 = new XdmDestination();
704
            transformer1.ApplyTemplates(input, results1);
705
            //Console.WriteLine("After phase 1:");
706
            //Console.WriteLine(results1.XdmNode.OuterXml);
707

    
708
            XdmDestination results2 = new XdmDestination();
709
            transformer2.GlobalContextItem = results1.XdmNode;
710
            transformer2.ApplyTemplates(results1.XdmNode, results2);
711
            //Console.WriteLine("After phase 2:");
712
            //Console.WriteLine(results2.XdmNode.OuterXml);
713

    
714
            XdmDestination results3 = new XdmDestination();
715
            transformer3.ApplyTemplates(results2.XdmNode, results3);
716
            Console.WriteLine("After phase 3:");
717
            Console.WriteLine(results3.XdmNode.OuterXml);
718
        }
719
    }
720

    
721
    /// <summary>
722
    /// Transform from an XDM tree to an XDM tree
723
    /// </summary>
724

    
725
    public class XsltXdmToXdm : Example
726
    {
727

    
728
        public override String testName
729
        {
730
            get { return "XsltXdmToXdm"; }
731
        }
732

    
733
        public override void run(Uri samplesDir)
734
        {
735
            // Create a Processor instance.
736
            Processor processor = new Processor();
737

    
738
            // Load the source document
739
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
740

    
741
            // Create a compiler
742
            XsltCompiler compiler = processor.NewXsltCompiler();
743

    
744
            // Compile the stylesheet
745
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
746

    
747
            // Run the transformation
748
            XdmDestination result = new XdmDestination();
749
            transformer.ApplyTemplates(input, result);
750

    
751
            // Serialize the result so we can see that it worked
752
            StringWriter sw = new StringWriter();
753
            result.XdmNode.WriteTo(new XmlTextWriter(sw));
754
            Console.WriteLine(sw.ToString());
755

    
756
            // Note: we don't do 
757
            //   result.XdmNode.WriteTo(new XmlTextWriter(Console.Out));
758
            // because that results in the Console.out stream being closed, 
759
            // with subsequent attempts to write to it being rejected.
760
        }
761
    }
762

    
763
    /// <summary>
764
    /// Run an XSLT transformation from an XDM tree, starting at a node that is not the document node
765
    /// </summary>
766

    
767
    public class XsltXdmElementToXdm : Example
768
    {
769

    
770
        public override String testName
771
        {
772
            get { return "XsltXdmElementToXdm"; }
773
        }
774

    
775
        public override void run(Uri samplesDir)
776
        {
777
            // Create a Processor instance.
778
            Processor processor = new Processor();
779

    
780
            // Load the source document
781
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
782

    
783
            // Navigate to the first grandchild
784
            XPathSelector eval = processor.NewXPathCompiler().Compile("/PLAY/FM[1]").Load();
785
            eval.ContextItem = input;
786
            input = (XdmNode)eval.EvaluateSingle();
787

    
788
            // Create an XSLT compiler
789
            XsltCompiler compiler = processor.NewXsltCompiler();
790

    
791
            // Compile the stylesheet
792
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
793

    
794
            // Run the transformation
795
            XdmDestination result = new XdmDestination();
796
            transformer.ApplyTemplates(input, result);
797

    
798
            // Serialize the result so we can see that it worked
799
            Console.WriteLine(result.XdmNode.OuterXml);
800
        }
801
    }
802

    
803
    /// <summary>
804
    /// Run a transformation from a DOM (System.Xml.Document) input to a DOM output
805
    /// </summary>
806

    
807
    public class XsltDomToDom : Example
808
    {
809

    
810
        public override String testName
811
        {
812
            get { return "XsltDomToDom"; }
813
        }
814

    
815
        public override void run(Uri samplesDir)
816
        {
817
            // Create a Processor instance.
818
            Processor processor = new Processor();
819

    
820
            // Load the source document (in practice, it would already exist as a DOM)
821
            XmlDocument doc = new XmlDocument();
822
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/othello.xml"));
823
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
824

    
825
            // Create a compiler
826
            XsltCompiler compiler = processor.NewXsltCompiler();
827

    
828
            // Compile the stylesheet
829
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
830

    
831
            // Run the transformation
832
            DomDestination result = new DomDestination();
833
            transformer.ApplyTemplates(input, result);
834

    
835
            // Serialize the result so we can see that it worked
836
            Console.WriteLine(result.XmlDocument.OuterXml);
837
        }
838
    }
839

    
840

    
841
    /// <summary>
842
    /// Run a transformation driven by an xml-stylesheet processing instruction in the source document
843
    /// </summary>
844

    
845
    public class XsltProcessingInstruction : Example
846
    {
847

    
848
        public override string testName
849
        {
850
            get { return "XsltProcessingInstruction"; }
851
        }
852

    
853
        public override void run(Uri samplesDir)
854
        {
855
            // Create a Processor instance.
856
            Processor processor = new Processor();
857
            XsltExecutable exec;
858

    
859
            // Load the source document
860
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
861
            //Console.WriteLine("=============== source document ===============");
862
            //Console.WriteLine(input.OuterXml);
863
            //Console.WriteLine("=========== end of source document ============");
864

    
865
            // Navigate to the xml-stylesheet processing instruction having the pseudo-attribute type=text/xsl;
866
            // then extract the value of the href pseudo-attribute if present
867

    
868
            String path = @"/processing-instruction(xml-stylesheet)[matches(.,'type\s*=\s*[''""]text/xsl[''""]')]" +
869
                    @"/replace(., '.*?href\s*=\s*[''""](.*?)[''""].*', '$1')";
870

    
871
            XPathSelector eval = processor.NewXPathCompiler().Compile(path).Load();
872
            eval.ContextItem = input;
873
            XdmAtomicValue hrefval = (XdmAtomicValue)eval.EvaluateSingle();
874
            String href = (hrefval == null ? null : hrefval.ToString());
875

    
876
            if (href == null || href == "")
877
            {
878
                Console.WriteLine("No suitable xml-stylesheet processing instruction found");
879
                return;
880

    
881
            }
882
            else if (href[0] == '#')
883
            {
884

    
885
                // The stylesheet is embedded in the source document and identified by a URI of the form "#id"
886

    
887
                Console.WriteLine("Locating embedded stylesheet with href = " + href);
888
                String idpath = "id('" + href.Substring(1) + "')";
889
                eval = processor.NewXPathCompiler().Compile(idpath).Load();
890
                eval.ContextItem = input;
891
                XdmNode node = (XdmNode)eval.EvaluateSingle();
892
                if (node == null)
893
                {
894
                    Console.WriteLine("No element found with ID " + href.Substring(1));
895
                    return;
896
                }
897
                exec = processor.NewXsltCompiler().Compile(node);
898

    
899
            }
900
            else
901
            {
902

    
903
                // The stylesheet is in an external document
904

    
905
                Console.WriteLine("Locating stylesheet at uri = " + new Uri(input.BaseUri, href));
906

    
907
                // Fetch and compile the referenced stylesheet
908
                exec = processor.NewXsltCompiler().Compile(new Uri(input.BaseUri, href.ToString()));
909
            }
910

    
911
            // Create a transformer 
912
            Xslt30Transformer transformer = exec.Load30();
913

    
914
            // Set the root node of the source document to be the global context item
915
            transformer.GlobalContextItem = input;
916

    
917
            // Run it       
918
            XdmDestination results = new XdmDestination();
919
            transformer.ApplyTemplates(input, results);
920
            Console.WriteLine(results.XdmNode.OuterXml);
921

    
922
        }
923
    }
924

    
925
    /// <summary>
926
    /// Run an XSLT transformation setting serialization properties from the calling application
927
    /// </summary>
928

    
929
    public class XsltSettingOutputProperties : Example
930
    {
931

    
932
        public override string testName
933
        {
934
            get { return "XsltSettingOutputProperties"; }
935
        }
936

    
937
        public override void run(Uri samplesDir)
938
        {
939
            // Create a Processor instance.
940
            Processor processor = new Processor();
941

    
942
            // Load the source document
943
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
944

    
945
            // Create a transformer for the stylesheet.
946
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
947

    
948
            // Create a serializer, with output to the standard output stream
949
            Serializer serializer = processor.NewSerializer();
950
            serializer.SetOutputProperty(Serializer.METHOD, "xml");
951
            serializer.SetOutputProperty(Serializer.INDENT, "no");
952
            serializer.SetOutputWriter(Console.Out);
953

    
954
            // Transform the source XML and serialize the result document
955
            transformer.ApplyTemplates(input, serializer);
956
        }
957

    
958
    }
959

    
960
    /// <summary>
961
    /// Run an XSLT transformation making use of an XmlResolver to resolve URIs at document build time, at stylesheet compile time 
962
    /// and at transformation run-time
963
    /// </summary>
964

    
965
    public class XsltUsingSourceResolver : Example
966
    {
967

    
968
        public override string testName
969
        {
970
            get { return "XsltUsingSourceResolver"; }
971
        }
972

    
973
        public override void run(Uri samplesDir)
974
        {
975

    
976
            // Create a Processor instance.
977
            Processor processor = new Processor();
978

    
979
            // Load the source document
980
            DocumentBuilder builder = processor.NewDocumentBuilder();
981
            UserXmlResolver buildTimeResolver = new UserXmlResolver();
982
            buildTimeResolver.Message = "** Calling build-time XmlResolver: ";
983
            builder.XmlResolver = buildTimeResolver;
984
            builder.BaseUri = samplesDir;
985

    
986
            String doc = "<!DOCTYPE doc [<!ENTITY e SYSTEM 'flamingo.txt'>]><doc>&e;</doc>";
987
            MemoryStream ms = new MemoryStream();
988
            StreamWriter tw = new StreamWriter(ms);
989
            tw.Write(doc);
990
            tw.Flush();
991
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
992
            XdmNode input = builder.Build(instr);
993

    
994
            // Create a transformer for the stylesheet.
995
            String stylesheet =
996
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>" +
997
                "<xsl:import href='empty.xslt'/>" +
998
                "<xsl:template match='/'>" +
999
                "<out note=\"{doc('heron.txt')}\" ><xsl:copy-of select='.'/></out>" +
1000
                "</xsl:template>" +
1001
                "</xsl:stylesheet>";
1002

    
1003
            XsltCompiler compiler = processor.NewXsltCompiler();
1004
            UserXmlResolver compileTimeResolver = new UserXmlResolver();
1005
            compileTimeResolver.Message = "** Calling compile-time XmlResolver: ";
1006
            compiler.XmlResolver = compileTimeResolver;
1007
            compiler.BaseUri = samplesDir;
1008
            Xslt30Transformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load30();
1009

    
1010
            // Set the user-written XmlResolver
1011
            UserXmlResolver runTimeResolver = new UserXmlResolver();
1012
            runTimeResolver.Message = "** Calling transformation-time XmlResolver: ";
1013
            transformer.InputXmlResolver = runTimeResolver;
1014

    
1015
            // Create a serializer
1016
            Serializer serializer = processor.NewSerializer();
1017
            serializer.SetOutputWriter(Console.Out);
1018

    
1019
            // Transform the source XML and serialize the result document
1020
            transformer.ApplyTemplates(input, serializer);
1021

    
1022
        }
1023
    }
1024

    
1025
    /// <summary>
1026
    /// Run an XSLT transformation displaying compile-time errors to the console
1027
    /// </summary>
1028

    
1029
    public class XsltDisplayingErrors : Example
1030
    {
1031

    
1032
        public override string testName
1033
        {
1034
            get { return "XsltDisplayingErrors"; }
1035
        }
1036

    
1037
        public override void run(Uri samplesDir)
1038
        {
1039
            // Create a Processor instance.
1040
            Processor processor = new Processor();
1041

    
1042
            // Create the XSLT Compiler
1043
            XsltCompiler compiler = processor.NewXsltCompiler();
1044

    
1045

    
1046
            // Define a stylesheet containing errors
1047
            String stylesheet =
1048
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
1049
                "<xsl:template name='eee:template'>\n" +
1050
                "  <xsl:value-of select='32'/>\n" +
1051
                "</xsl:template>\n" +
1052
                "<xsl:template name='main'>\n" +
1053
                "  <xsl:value-of select='$var'/>\n" +
1054
                "</xsl:template>\n" +
1055
                "</xsl:stylesheet>";
1056

    
1057

    
1058
            // Attempt to compile the stylesheet and display the errors
1059
            try
1060
            {
1061
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1062
                compiler.Compile(new XmlTextReader(new StringReader(stylesheet)));
1063
                Console.WriteLine("Stylesheet compilation succeeded");
1064
            }
1065
            catch (Exception)
1066
            {
1067
                Console.WriteLine("Stylesheet compilation failed");
1068
            }
1069

    
1070

    
1071
        }
1072
    }
1073

    
1074
    /// <summary>
1075
    /// Run an XSLT transformation capturing compile-time errors within the application
1076
    /// </summary>
1077

    
1078
    public class XsltCapturingErrors : Example
1079
    {
1080

    
1081
        public override string testName
1082
        {
1083
            get { return "XsltCapturingErrors"; }
1084
        }
1085

    
1086
        public override void run(Uri samplesDir)
1087
        {
1088
            // Create a Processor instance.
1089
            Processor processor = new Processor();
1090

    
1091
            // Create the XSLT Compiler
1092
            XsltCompiler compiler = processor.NewXsltCompiler();
1093

    
1094
            // Create a list to hold the error information
1095
            compiler.ErrorList = new List<StaticError>();
1096

    
1097
            // Define a stylesheet containing errors
1098
            String stylesheet =
1099
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
1100
                "<xsl:template name='fff:template'>\n" +
1101
                "  <xsl:value-of select='32'/>\n" +
1102
                "</xsl:template>\n" +
1103
                "<xsl:template name='main'>\n" +
1104
                "  <xsl:value-of select='$var'/>\n" +
1105
                "</xsl:template>\n" +
1106
                "</xsl:stylesheet>";
1107

    
1108

    
1109
            // Attempt to compile the stylesheet and display the errors
1110
            try
1111
            {
1112
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1113
                compiler.Compile(new StringReader(stylesheet));
1114
                Console.WriteLine("Stylesheet compilation succeeded");
1115
            }
1116
            catch (Exception)
1117
            {
1118
                Console.WriteLine("Stylesheet compilation failed with " + compiler.ErrorList.Count + " errors");
1119
                foreach (StaticError error in compiler.ErrorList)
1120
                {
1121
                    Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
1122
                }
1123
            }
1124
        }
1125
    }
1126

    
1127
    /// <summary>
1128
    /// Run an XSLT transformation capturing run-time messages within the application
1129
    /// </summary>
1130

    
1131
    public class XsltCapturingMessages : Example
1132
    {
1133

    
1134
        public override string testName
1135
        {
1136
            get { return "XsltCapturingMessages"; }
1137
        }
1138

    
1139
        public override void run(Uri samplesDir)
1140
        {
1141

    
1142
            // Create a Processor instance.
1143
            Processor processor = new Processor();
1144

    
1145
            // Create the XSLT Compiler
1146
            XsltCompiler compiler = processor.NewXsltCompiler();
1147

    
1148
            // Define a stylesheet that generates messages
1149
            String stylesheet =
1150
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1151
                "<xsl:template name='main'>\n" +
1152
                "  <xsl:message><a>starting</a></xsl:message>\n" +
1153
                "  <out><xsl:value-of select='current-date()'/></out>\n" +
1154
                "  <xsl:message><a>finishing</a></xsl:message>\n" +
1155
                "</xsl:template>\n" +
1156
                "</xsl:stylesheet>";
1157

    
1158
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1159
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1160

    
1161

    
1162
            // Create a transformer for the stylesheet.
1163
            Xslt30Transformer transformer = exec.Load30();
1164

    
1165
            // Create a Listener to which messages will be written
1166
            transformer.MessageListener = new UserMessageListener();
1167

    
1168
            // Create a serializer, with output to the standard output stream
1169
            Serializer serializer = processor.NewSerializer();
1170
            serializer.SetOutputWriter(Console.Out);
1171

    
1172
            // Transform the source XML, calling a named initial template, and serialize the result document
1173
            transformer.CallTemplate(new QName("", "main"), serializer);
1174
        }
1175

    
1176
    }
1177

    
1178
    ///
1179
    /// Example user-written message listener
1180
    ///
1181

    
1182
    public class UserMessageListener : IMessageListener
1183
    {
1184

    
1185
        public void Message(XdmNode content, bool terminate, IXmlLocation location)
1186
        {
1187
            Console.Out.WriteLine("MESSAGE terminate=" + (terminate ? "yes" : "no") + " at " + DateTime.Now);
1188
            Console.Out.WriteLine("From instruction at line " + location.LineNumber +
1189
                    " of " + location.BaseUri);
1190
            Console.Out.WriteLine(">>" + content.StringValue);
1191
        }
1192
    }
1193

    
1194

    
1195
    /// <summary>
1196
    /// Run an XSLT transformation producing multiple output documents
1197
    /// </summary>
1198

    
1199
    public class XsltMultipleOutput : Example
1200
    {
1201

    
1202
        public override string testName
1203
        {
1204
            get { return "XsltMultipleOutput"; }
1205
        }
1206

    
1207
        public override void run(Uri samplesDir)
1208
        {
1209
            // Create a Processor instance.
1210
            Processor processor = new Processor();
1211
            processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
1212

    
1213
            // Load the source document
1214
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1215

    
1216
            // Create a transformer for the stylesheet.
1217
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/play.xsl")).Load30();
1218

    
1219
            // Set the required stylesheet parameter
1220
            Dictionary<QName, XdmValue> parameters = new Dictionary<QName, XdmValue>();
1221
            parameters.Add(new QName("", "", "dir"), new XdmAtomicValue(samplesDir.ToString() + "play"));
1222
            transformer.SetStylesheetParameters(parameters);
1223

    
1224
            // Create a serializer, with output to the standard output stream
1225
            Serializer serializer = processor.NewSerializer();
1226
            serializer.SetOutputWriter(Console.Out);
1227

    
1228
            // Transform the source XML and serialize the result document
1229
            transformer.ApplyTemplates(input, serializer);
1230

    
1231
        }
1232

    
1233
    }
1234

    
1235

    
1236
    /// <summary>
1237
    /// Run an XSLT transformation using the id() function, with DTD validation
1238
    /// </summary>
1239

    
1240
    public class XsltUsingIdFunction : Example
1241
    {
1242

    
1243
        public override string testName
1244
        {
1245
            get { return "XsltUsingIdFunction"; }
1246
        }
1247

    
1248
        public override void run(Uri samplesDir)
1249
        {
1250
            // Create a Processor instance
1251
            Processor processor = new Processor();
1252

    
1253
            // Load the source document. The Microsoft .NET parser does not report attributes of type ID. The only
1254
            // way to use the function is therefore (a) to use a different parser, or (b) to use xml:id instead. We
1255
            // choose the latter course.
1256

    
1257
            String doc = "<!DOCTYPE table [" +
1258
                "<!ELEMENT table (row*)>" +
1259
                "<!ELEMENT row EMPTY>" +
1260
                "<!ATTLIST row xml:id ID #REQUIRED>" +
1261
                "<!ATTLIST row value CDATA #REQUIRED>]>" +
1262
                "<table><row xml:id='A123' value='green'/><row xml:id='Z789' value='blue'/></table>";
1263

    
1264
            DocumentBuilder builder = processor.NewDocumentBuilder();
1265
            builder.DtdValidation = true;
1266
            builder.BaseUri = samplesDir;
1267
            MemoryStream ms = new MemoryStream();
1268
            StreamWriter tw = new StreamWriter(ms);
1269
            tw.Write(doc);
1270
            tw.Flush();
1271
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1272
            XdmNode input = builder.Build(instr);
1273

    
1274
            // Define a stylesheet that uses the id() function
1275
            String stylesheet =
1276
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1277
                "<xsl:template match='/'>\n" +
1278
                "  <xsl:copy-of select=\"id('Z789')\"/>\n" +
1279
                "</xsl:template>\n" +
1280
                "</xsl:stylesheet>";
1281

    
1282
            XsltCompiler compiler = processor.NewXsltCompiler();
1283
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1284
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1285

    
1286
            // Create a transformer for the stylesheet
1287
            Xslt30Transformer transformer = exec.Load30();
1288

    
1289
            // Set the destination
1290
            XdmDestination results = new XdmDestination();
1291

    
1292
            // Transform the XML
1293
            transformer.ApplyTemplates(input, results);
1294

    
1295
            // Show the result
1296
            Console.WriteLine(results.XdmNode.ToString());
1297

    
1298
        }
1299

    
1300
    }
1301

    
1302
    /// <summary>
1303
    /// Show a transformation using a user-written result document handler. This example
1304
    /// captures each of the result documents in a DOM, and creates a Hashtable that indexes
1305
    /// the DOM trees according to their absolute URI. On completion, it writes all the DOMs
1306
    /// to the standard output.
1307
    /// </summary>
1308

    
1309
    public class XsltUsingResultHandler : Example
1310
    {
1311

    
1312
        public override string testName
1313
        {
1314
            get { return "XsltUsingResultHandler"; }
1315
        }
1316

    
1317
        public override void run(Uri samplesDir)
1318
        {
1319
            // Create a Processor instance.
1320
            Processor processor = new Processor();
1321

    
1322
            // Load the source document
1323
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1324

    
1325
            // Define a stylesheet that splits the document up
1326
            String stylesheet =
1327
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1328
                "<xsl:template match='/'>\n" +
1329
                "  <xsl:for-each select='//ACT'>\n" +
1330
                "    <xsl:result-document href='{position()}.xml'>\n" +
1331
                "      <xsl:copy-of select='TITLE'/>\n" +
1332
                "    </xsl:result-document>\n" +
1333
                "  </xsl:for-each>\n" +
1334
                "</xsl:template>\n" +
1335
                "</xsl:stylesheet>";
1336

    
1337
            XsltCompiler compiler = processor.NewXsltCompiler();
1338
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1339
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1340

    
1341
            // Create a transformer for the stylesheet.
1342
            Xslt30Transformer transformer = exec.Load30();
1343

    
1344
            // Establish the result document handler
1345
            Hashtable results = new Hashtable();
1346
            transformer.ResultDocumentHandler = new UserResultDocumentHandler(results);
1347

    
1348
            // Transform the source XML to a NullDestination (because we only want the secondary result files).
1349
            NullDestination destination = new NullDestination();
1350
            destination.BaseUri = samplesDir;
1351
            transformer.ApplyTemplates(input, destination);
1352

    
1353
            // Process the captured DOM results
1354
            foreach (DictionaryEntry entry in results)
1355
            {
1356
                string uri = (string)entry.Key;
1357
                Console.WriteLine("\nResult File " + uri);
1358
                DomDestination dom = (DomDestination)results[uri];
1359
                Console.Write(dom.XmlDocument.OuterXml);
1360
            }
1361

    
1362
        }
1363

    
1364
    }
1365

    
1366
    /// <summary>
1367
    /// Show a transformation using a registered collection
1368
    /// </summary>
1369

    
1370
    public class XsltUsingRegisteredCollection : Example
1371
    {
1372

    
1373
        public override string testName
1374
        {
1375
            get { return "XsltUsingRegisteredCollection"; }
1376
        }
1377

    
1378
        public override void run(Uri samplesDir)
1379
        {
1380
            // Create a Processor instance.
1381
            Processor processor = new Processor();
1382

    
1383
            // Define a stylesheet that uses the collection() function
1384
            String stylesheet =
1385
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1386
                "<xsl:template name='main'>\n" +
1387
                " <out>\n" +
1388
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1389
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1390
                "  </xsl:for-each><zzz/>\n" +
1391
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1392
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1393
                "  </xsl:for-each>\n" +
1394
                " </out>\n" +
1395
                "</xsl:template>\n" +
1396
                "</xsl:stylesheet>";
1397

    
1398
            // Register a named collection
1399
            Uri[] documentList = new Uri[2];
1400
            documentList[0] = new Uri(samplesDir, "data/othello.xml");
1401
            documentList[1] = new Uri(samplesDir, "data/books.xml");
1402
            processor.RegisterCollection(new Uri("http://www.example.org/my-collection"), documentList);
1403

    
1404
            XsltCompiler compiler = processor.NewXsltCompiler();
1405
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1406
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1407

    
1408
            // Create a transformer for the stylesheet.
1409
            Xslt30Transformer transformer = exec.Load30();
1410

    
1411
            // Set the destination
1412
            XdmDestination results = new XdmDestination();
1413

    
1414
            // Transform the XML, calling a named initial template
1415
            transformer.CallTemplate(new QName("", "main"), results);
1416

    
1417
            // Show the result
1418
            Console.WriteLine(results.XdmNode.ToString());
1419

    
1420
        }
1421
    }
1422

    
1423
    /// <summary>
1424
    /// Show a transformation using a collection that maps to a directory
1425
    /// </summary>
1426

    
1427
    public class XsltUsingDirectoryCollection : Example
1428
    {
1429

    
1430
        public override string testName
1431
        {
1432
            get { return "XsltUsingDirectoryCollection"; }
1433
        }
1434

    
1435
        public override void run(Uri samplesDir)
1436
        {
1437
            // Create a Processor instance.
1438
            Processor processor = new Processor();
1439

    
1440
            // Define a stylesheet that uses the collection() function
1441
            String stylesheet =
1442
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1443
                "<xsl:template name='main'>\n" +
1444
                " <out>\n" +
1445
                "  <xsl:for-each select=\"collection('" + samplesDir + "?recurse=yes;select=*.xml;on-error=warning')\">\n" +
1446
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1447
                "  </xsl:for-each><zzz/>\n" +
1448
                " </out>\n" +
1449
                "</xsl:template>\n" +
1450
                "</xsl:stylesheet>";
1451

    
1452

    
1453
            XsltCompiler compiler = processor.NewXsltCompiler();
1454
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1455
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1456

    
1457
            // Create a transformer for the stylesheet.
1458
            Xslt30Transformer transformer = exec.Load30();
1459

    
1460
            // Set the destination
1461
            XdmDestination results = new XdmDestination();
1462

    
1463
            // Transform the XML, calling a named initial template
1464
            transformer.CallTemplate(new QName("", "main"), results);
1465

    
1466
            // Show the result
1467
            Console.WriteLine(results.XdmNode.ToString());
1468

    
1469
        }
1470

    
1471
    }
1472

    
1473
    /// <summary>
1474
    /// Show a transformation using calls to integrated extension functions (full API)
1475
    /// </summary>
1476

    
1477
    public class XsltIntegratedExtension : Example
1478
    {
1479

    
1480
        public override string testName
1481
        {
1482
            get { return "XsltIntegratedExtension"; }
1483
        }
1484

    
1485
        public override void run(Uri samplesDir)
1486
        {
1487

    
1488
            // Create a Processor instance.
1489
            Processor processor = new Processor();
1490

    
1491
            // Identify the Processor version
1492
            Console.WriteLine(processor.ProductVersion);
1493

    
1494
            // Set diagnostics
1495
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1496

    
1497
            // Create the stylesheet
1498
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1499
                @" xmlns:math='http://example.math.co.uk/demo' " +
1500
                @" xmlns:env='http://example.env.co.uk/demo' " +
1501
                @" exclude-result-prefixes='math env'> " +
1502
                @" <xsl:template name='go'> " +
1503
                @" <out sqrt2='{math:sqrt(2.0e0)}' " +
1504
                @" defaultNamespace='{env:defaultNamespace()}' " +
1505
                @" sqrtEmpty='{math:sqrt(())}'> " +
1506
                @" <defaultNS value='{env:defaultNamespace()}' xsl:xpath-default-namespace='http://default.namespace.com/' /> " +
1507
                @" </out> " +
1508
                @" </xsl:template></xsl:transform>";
1509

    
1510
            // Register the integrated extension functions math:sqrt and env:defaultNamespace
1511
            processor.RegisterExtensionFunction(new Sqrt());
1512
            processor.RegisterExtensionFunction(new DefaultNamespace());
1513

    
1514
            // Create a transformer for the stylesheet.
1515
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
1516

    
1517
            // Create a serializer, with output to the standard output stream
1518
            Serializer serializer = processor.NewSerializer();
1519
            serializer.SetOutputWriter(Console.Out);
1520
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1521

    
1522
            // Transform the source XML, calling a named initial template, and serialize the result document
1523
            transformer.CallTemplate(new QName("go"), serializer);
1524
        }
1525

    
1526
    }
1527

    
1528
    /// <summary>
1529
    /// Example extension function to compute a square root, using the full API
1530
    /// </summary>
1531

    
1532
    public class Sqrt : ExtensionFunctionDefinition
1533
    {
1534
        public override QName FunctionName
1535
        {
1536
            get
1537
            {
1538
                return new QName("http://example.math.co.uk/demo", "sqrt");
1539
            }
1540
        }
1541

    
1542
        public override int MinimumNumberOfArguments
1543
        {
1544
            get
1545
            {
1546
                return 1;
1547
            }
1548
        }
1549

    
1550
        public override int MaximumNumberOfArguments
1551
        {
1552
            get
1553
            {
1554
                return 1;
1555
            }
1556
        }
1557

    
1558
        public override XdmSequenceType[] ArgumentTypes
1559
        {
1560
            get
1561
            {
1562
                return new XdmSequenceType[]{
1563
                    new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1564
                };
1565
            }
1566
        }
1567

    
1568
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1569
        {
1570
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?');
1571
        }
1572

    
1573
        public override bool TrustResultType
1574
        {
1575
            get
1576
            {
1577
                return true;
1578
            }
1579
        }
1580

    
1581

    
1582
        public override ExtensionFunctionCall MakeFunctionCall()
1583
        {
1584
            return new SqrtCall();
1585
        }
1586
    }
1587

    
1588
    internal class SqrtCall : ExtensionFunctionCall
1589
    {
1590
        public override IEnumerator<XdmItem> Call(IEnumerator<XdmItem>[] arguments, DynamicContext context)
1591
        {
1592
            Boolean exists = arguments[0].MoveNext();
1593
            if (exists)
1594
            {
1595
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
1596
                double val = (double)arg.Value;
1597
                double sqrt = System.Math.Sqrt(val);
1598
                return new XdmAtomicValue(sqrt).GetEnumerator();
1599
            }
1600
            else
1601
            {
1602
                return EmptyEnumerator<XdmItem>.INSTANCE;
1603
            }
1604
        }
1605
    }
1606

    
1607
    /// <summary>
1608
    /// Example extension function to return the default namespace from the static context
1609
    /// </summary>
1610

    
1611
    public class DefaultNamespace : ExtensionFunctionDefinition
1612
    {
1613
        public override QName FunctionName
1614
        {
1615
            get
1616
            {
1617
                return new QName("http://example.env.co.uk/demo", "defaultNamespace");
1618
            }
1619
        }
1620

    
1621
        public override int MinimumNumberOfArguments
1622
        {
1623
            get
1624
            {
1625
                return 0;
1626
            }
1627
        }
1628

    
1629
        public override int MaximumNumberOfArguments
1630
        {
1631
            get
1632
            {
1633
                return 0;
1634
            }
1635
        }
1636

    
1637
        public override XdmSequenceType[] ArgumentTypes
1638
        {
1639
            get
1640
            {
1641
                return new XdmSequenceType[] { };
1642
            }
1643
        }
1644

    
1645
        public override bool DependsOnFocus
1646
        {
1647
            get
1648
            {
1649
                return true;
1650
                // actually it depends on the static context rather than the focus; but returning true is necessary
1651
                // to avoid the call being extracted to a global variable.
1652
            }
1653
        }
1654

    
1655
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1656
        {
1657
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?');
1658
        }
1659

    
1660
        public override bool TrustResultType
1661
        {
1662
            get
1663
            {
1664
                return true;
1665
            }
1666
        }
1667

    
1668
        public override ExtensionFunctionCall MakeFunctionCall()
1669
        {
1670
            return new DefaultNamespaceCall();
1671
        }
1672
    }
1673

    
1674
    internal class DefaultNamespaceCall : ExtensionFunctionCall
1675
    {
1676
        private string defaultNamespace;
1677

    
1678
        public override void SupplyStaticContext(StaticContext context)
1679
        {
1680
            defaultNamespace = context.GetNamespaceForPrefix("");
1681
        }
1682

    
1683
        public override IEnumerator<XdmItem> Call(IEnumerator<XdmItem>[] arguments, DynamicContext context)
1684
        {
1685
            if (defaultNamespace != null)
1686
            {
1687
                return new XdmAtomicValue(defaultNamespace).GetEnumerator();
1688
            }
1689
            else
1690
            {
1691
                return EmptyEnumerator<XdmItem>.INSTANCE;
1692
            }
1693
        }
1694
    }
1695

    
1696
    /// <summary>
1697
    /// Show a transformation using calls to an integrated extension function (simple API)
1698
    /// </summary>
1699

    
1700
    public class XsltSimpleExtension : Example
1701
    {
1702

    
1703
        public override string testName
1704
        {
1705
            get { return "XsltSimpleExtension"; }
1706
        }
1707

    
1708
        public override void run(Uri samplesDir)
1709
        {
1710

    
1711
            // Create a Processor instance.
1712
            Processor processor = new Processor();
1713

    
1714
            // Identify the Processor version
1715
            Console.WriteLine(processor.ProductVersion);
1716

    
1717
            // Set diagnostics
1718
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1719

    
1720
            // Create the stylesheet
1721
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1722
                @" xmlns:math='http://example.math.co.uk/demo'> " +
1723
                @" <xsl:template name='go'> " +
1724
                @" <out sqrt2='{math:sqrtSimple(2.0e0)}' " +
1725
                @" sqrtEmpty='{math:sqrtSimple(())}'/> " +
1726
                @" </xsl:template></xsl:transform>";
1727

    
1728
            // Register the integrated extension function math:sqrtSimple
1729
            processor.RegisterExtensionFunction(new SqrtSimple());
1730

    
1731
            // Create a transformer for the stylesheet.
1732
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
1733

    
1734
            // Create a serializer, with output to the standard output stream
1735
            Serializer serializer = processor.NewSerializer();
1736
            serializer.SetOutputWriter(Console.Out);
1737
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1738

    
1739
            // Transform the source XML, calling a named initial template, and serialize the result document
1740
            transformer.CallTemplate(new QName("go"), serializer);
1741
        }
1742

    
1743
    }
1744

    
1745
    /// <summary>
1746
    /// Example extension function to compute a square root, using the simple API
1747
    /// </summary>
1748

    
1749
    public class SqrtSimple : ExtensionFunction
1750
    {
1751
        public XdmValue Call(XdmValue[] arguments)
1752
        {
1753
            if (!(arguments[0] is XdmEmptySequence))
1754
            {
1755
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].ItemAt(0);
1756
                double val = (double)arg.Value;
1757
                double sqrt = System.Math.Sqrt(val);
1758
                return new XdmAtomicValue(sqrt);
1759
            }
1760
            else
1761
            {
1762
                return XdmValue.MakeValue((double)0);
1763
            }
1764
        }
1765

    
1766
        public XdmSequenceType[] GetArgumentTypes()
1767
        {
1768
            return new XdmSequenceType[]{
1769
                new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1770
            };
1771
        }
1772

    
1773
        public QName GetName()
1774
        {
1775
            return new QName("http://example.math.co.uk/demo", "sqrtSimple");
1776
        }
1777

    
1778
        public XdmSequenceType GetResultType()
1779
        {
1780
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), ' ');
1781
        }
1782
    }
1783

    
1784
    /// <summary>
1785
    /// Show a query producing a document as its result and serializing this to a FileStream
1786
    /// </summary>
1787

    
1788
    public class XQueryToStream : Example
1789
    {
1790

    
1791
        public override string testName
1792
        {
1793
            get { return "XQueryToStream"; }
1794
        }
1795

    
1796
        public override void run(Uri samplesDir)
1797
        {
1798
            Processor processor = new Processor();
1799
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1800
            compiler.BaseUri = samplesDir.ToString();
1801
            compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
1802
            XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>");
1803
            XQueryEvaluator eval = exp.Load();
1804
            Serializer qout = processor.NewSerializer();
1805
            qout.SetOutputProperty(Serializer.METHOD, "xml");
1806
            qout.SetOutputProperty(Serializer.INDENT, "yes");
1807
            qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write));
1808
            Console.WriteLine("Output written to testoutput.xml");
1809
            eval.Run(qout);
1810
        }
1811

    
1812
    }
1813

    
1814
    /// <summary>
1815
    /// Show a query producing a single atomic value as its result and returning the value
1816
    /// to the C# application
1817
    /// </summary>
1818

    
1819
    public class XQueryToAtomicValue : Example
1820
    {
1821

    
1822
        public override string testName
1823
        {
1824
            get { return "XQueryToAtomicValue"; }
1825
        }
1826

    
1827
        public override void run(Uri samplesDir)
1828
        {
1829
            Processor processor = new Processor();
1830
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1831
            XQueryExecutable exp = compiler.Compile("avg(for $i in 1 to 10 return $i * $i)");
1832
            XQueryEvaluator eval = exp.Load();
1833
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
1834
            Console.WriteLine("Result type: " + result.Value.GetType());
1835
            Console.WriteLine("Result value: " + (decimal)result.Value);
1836
        }
1837

    
1838
	}
1839

    
1840
	/// <summary>
1841
	/// Show a query producing a sequence as its result and returning the sequence
1842
	/// to the C# application in the form of an iterator. For each item in the
1843
	/// result, its string value is output.
1844
	/// </summary>
1845

    
1846
	public class XQueryToSequence : Example
1847
	{
1848

    
1849
		public override string testName
1850
		{
1851
			get { return "XQueryToSequence"; }
1852
		}
1853

    
1854
		public override void run(Uri samplesDir)
1855
		{
1856
			Processor processor = new Processor();
1857
			XQueryCompiler compiler = processor.NewXQueryCompiler();
1858
			XQueryExecutable exp = compiler.Compile("for $i in 1 to 10 return $i * $i");
1859
			XQueryEvaluator eval = exp.Load();
1860
			XdmValue value = eval.Evaluate();
1861
            foreach (XdmItem item in value)
1862
            {
1863
				Console.WriteLine(item.ToString());
1864
			}
1865

    
1866
		}
1867

    
1868
	}
1869

    
1870
    /// <summary>
1871
    /// Show a query producing a DOM as its input and producing a DOM as its output
1872
    /// </summary>
1873

    
1874
    public class XQueryToDom : Example
1875
    {
1876

    
1877
        public override string testName
1878
        {
1879
            get { return "XQueryToDom"; }
1880
        }
1881

    
1882
        public override void run(Uri samplesDir)
1883
        {
1884
            Processor processor = new Processor();
1885

    
1886
            XmlDocument input = new XmlDocument();
1887
            input.Load(new Uri(samplesDir, "data/books.xml").ToString());
1888
            XdmNode indoc = processor.NewDocumentBuilder().Build(new XmlNodeReader(input));
1889

    
1890
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1891
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
1892
            XQueryEvaluator eval = exp.Load();
1893
            eval.ContextItem = indoc;
1894
            DomDestination qout = new DomDestination();
1895
            eval.Run(qout);
1896
            XmlDocument outdoc = qout.XmlDocument;
1897
            Console.WriteLine(outdoc.OuterXml);
1898
        }
1899

    
1900
    }
1901

    
1902
    /// <summary>
1903
    /// Show a query producing a Saxon tree as its input and producing a Saxon tree as its output
1904
    /// </summary>
1905

    
1906
    public class XQueryToXdm : Example
1907
    {
1908

    
1909
        public override string testName
1910
        {
1911
            get { return "XQueryToXdm"; }
1912
        }
1913

    
1914
        public override void run(Uri samplesDir)
1915
        {
1916
            Processor processor = new Processor();
1917

    
1918
            DocumentBuilder loader = processor.NewDocumentBuilder();
1919
            loader.BaseUri = new Uri(samplesDir, "data/books.xml");
1920
            XdmNode indoc = loader.Build(loader.BaseUri);
1921

    
1922
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1923
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
1924
            XQueryEvaluator eval = exp.Load();
1925
            eval.ContextItem = indoc;
1926
            XdmDestination qout = new XdmDestination();
1927
            eval.Run(qout);
1928
            XdmNode outdoc = qout.XdmNode;
1929
            Console.WriteLine(outdoc.OuterXml);
1930
        }
1931

    
1932
    }
1933

    
1934
    /// <summary>
1935
    /// Show a query making a direct call to a user-defined function defined in the query
1936
    /// </summary>
1937

    
1938
    public class XQueryCallFunction : Example
1939
    {
1940

    
1941
        public override string testName
1942
        {
1943
            get { return "XQueryCallFunction"; }
1944
        }
1945

    
1946
        public override void run(Uri samplesDir)
1947
        {
1948
            Processor processor = new Processor();
1949

    
1950
            XQueryCompiler qc = processor.NewXQueryCompiler();
1951
            Uri uri = new Uri(samplesDir, "data/books.xml");
1952
            XQueryExecutable exp1 = qc.Compile("declare namespace f='f.ns';" +
1953
                   "declare variable $z := 1 + xs:integer(doc-available('" + uri.ToString() + "'));" +
1954
                   "declare variable $p as xs:integer external;" +
1955
                   "declare function f:t1($v1 as xs:integer) { " +
1956
                   "   $v1 div $z + $p" +
1957
                   "};" +
1958
                   "10");
1959
            XQueryEvaluator ev = exp1.Load();
1960
            ev.SetExternalVariable(new QName("", "p"), new XdmAtomicValue(39));
1961
            XdmValue v1 = new XdmAtomicValue(10);
1962
            XdmValue result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
1963
            Console.WriteLine("First result (expected 44): " + result.ToString());
1964
            v1 = new XdmAtomicValue(20);
1965
            result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
1966
            Console.WriteLine("Second result (expected 49): " + result.ToString());
1967
        }
1968

    
1969
    }
1970

    
1971
    /// <summary>
1972
    /// Show a query reading an input document using an XmlReader (the .NET XML parser)
1973
    /// </summary>
1974

    
1975
    public class XQueryFromXmlReader : Example
1976
    {
1977

    
1978
        public override string testName
1979
        {
1980
            get { return "XQueryFromXmlReader"; }
1981
        }
1982

    
1983
        public override void run(Uri samplesDir)
1984
        {
1985
            Processor processor = new Processor();
1986

    
1987
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
1988
            XmlTextReader reader = new XmlTextReader(inputFileName,
1989
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
1990
            reader.Normalization = true;
1991

    
1992
            // Add a validating reader - needed in case there are entity references
1993
            XmlReaderSettings settings = new XmlReaderSettings();
1994
            settings.ValidationType = ValidationType.DTD;
1995
            settings.DtdProcessing = DtdProcessing.Parse;
1996
            XmlReader validator = XmlReader.Create(reader, settings);
1997

    
1998
            XdmNode doc = processor.NewDocumentBuilder().Build(validator);
1999

    
2000
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2001
            XQueryExecutable exp = compiler.Compile("/");
2002
            XQueryEvaluator eval = exp.Load();
2003
            eval.ContextItem = doc;
2004
            Serializer qout = processor.NewSerializer();
2005
            qout.SetOutputProperty(Serializer.METHOD, "xml");
2006
            qout.SetOutputProperty(Serializer.INDENT, "yes");
2007
            qout.SetOutputStream(new FileStream("testoutput2.xml", FileMode.Create, FileAccess.Write));
2008
            Console.WriteLine("Output written to testoutput2.xml");
2009
            eval.Run(qout);
2010
        }
2011

    
2012
    }
2013

    
2014
    /// <summary>
2015
    /// Show a query producing a sequence as its result and returning the sequence
2016
    /// to the C# application in the form of an iterator. The sequence is then
2017
    /// output by serializing each item individually, with each item on a new line.
2018
    /// </summary>
2019

    
2020
    public class XQueryToSerializedSequence : Example
2021
    {
2022

    
2023
        public override string testName
2024
        {
2025
            get { return "XQueryToSerializedSequence"; }
2026
        }
2027

    
2028
        public override void run(Uri samplesDir)
2029
        {
2030
            Processor processor = new Processor();
2031
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2032
            XmlTextReader reader = new XmlTextReader(inputFileName,
2033
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2034
            reader.Normalization = true;
2035

    
2036
            // Add a validating reader - needed in case there are entity references
2037
            XmlReaderSettings settings = new XmlReaderSettings();
2038
            settings.ValidationType = ValidationType.DTD;
2039
            settings.DtdProcessing = DtdProcessing.Parse;
2040
            XmlReader validator = XmlReader.Create(reader, settings);
2041

    
2042
            XdmNode doc = processor.NewDocumentBuilder().Build(reader);
2043

    
2044
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2045
            XQueryExecutable exp = compiler.Compile("//ISBN");
2046
            XQueryEvaluator eval = exp.Load();
2047
            eval.ContextItem = doc;
2048

    
2049
            foreach (XdmNode node in eval)
2050
            {
2051
                Console.WriteLine(node.OuterXml);
2052
            }
2053
        }
2054

    
2055
    }
2056

    
2057
    /// <summary>
2058
    /// Show a query that takes a parameter (external variable) as input.
2059
    /// The query produces a single atomic value as its result and returns the value
2060
    /// to the C# application. 
2061
    /// </summary>
2062

    
2063
    public class XQueryUsingParameter : Example
2064
    {
2065

    
2066
        public override string testName
2067
        {
2068
            get { return "XQueryUsingParameter"; }
2069
        }
2070

    
2071
        public override void run(Uri samplesDir)
2072
        {
2073
            Processor processor = new Processor();
2074
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2075
            compiler.DeclareNamespace("p", "http://saxon.sf.net/ns/p");
2076
            XQueryExecutable exp = compiler.Compile(
2077
                    "declare variable $p:in as xs:integer external; $p:in * $p:in");
2078
            XQueryEvaluator eval = exp.Load();
2079
            eval.SetExternalVariable(new QName("http://saxon.sf.net/ns/p", "p:in"), new XdmAtomicValue(12));
2080
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2081
            Console.WriteLine("Result type: " + result.Value.GetType());
2082
            Console.WriteLine("Result value: " + (long)result.Value);
2083
        }
2084

    
2085
    }
2086

    
2087
    /// <summary>
2088
    /// Show a query consisting of two modules, using a QueryResolver to resolve
2089
    /// the "import module" declaration
2090
    /// </summary>
2091

    
2092
    public class XQueryMultiModule : Example
2093
    {
2094

    
2095
        public override string testName
2096
        {
2097
            get { return "XQueryMultiModule"; }
2098
        }
2099

    
2100
        public override void run(Uri samplesDir)
2101
        {
2102

    
2103
            String mod1 = "import module namespace m2 = 'http://www.example.com/module2';" +
2104
                          "m2:square(3)";
2105

    
2106
            String mod2 = "module namespace m2 = 'http://www.example.com/module2';" +
2107
                          "declare function m2:square($p) { $p * $p };";
2108

    
2109
            Processor processor = new Processor();
2110
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2111

    
2112
            InlineModuleResolver resolver = new InlineModuleResolver();
2113
            resolver.AddModule(new Uri("http://www.example.com/module2"), mod2);
2114
            compiler.QueryResolver = resolver;
2115
            XQueryExecutable exp = compiler.Compile(mod1);
2116
            XQueryEvaluator eval = exp.Load();
2117

    
2118
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2119
            Console.WriteLine("Result type: " + result.Value.GetType());
2120
            Console.WriteLine("Result value: " + (long)result.Value);
2121
        }
2122

    
2123
        // A simple QueryResolver designed to show that the actual query
2124
        // text can come from anywhere: in this case, the resolver maintains
2125
        // a simple mapping of module URIs onto strings.
2126

    
2127
        public class InlineModuleResolver : IQueryResolver
2128
        {
2129

    
2130
            private Hashtable modules = new Hashtable();
2131

    
2132
            public void AddModule(Uri moduleName, String moduleText)
2133
            {
2134
                modules.Add(moduleName, moduleText);
2135
            }
2136

    
2137
            public Uri[] GetModules(String moduleUri, Uri baseUri, String[] locationHints)
2138
            {
2139
                Uri[] result = { new Uri(moduleUri) };
2140
                return result;
2141
            }
2142

    
2143
            public Object GetEntity(Uri absoluteUri)
2144
            {
2145
                return modules[absoluteUri];
2146
            }
2147
        }
2148

    
2149
    }
2150

    
2151

    
2152
    public class UriConnection
2153
    {
2154

    
2155
        // Get a stream for reading from a file:// URI
2156

    
2157
        public static Stream getReadableUriStream(Uri uri)
2158
        {
2159
            WebRequest request = (WebRequest)WebRequest.Create(uri);
2160
            return request.GetResponse().GetResponseStream();
2161
        }
2162

    
2163
        // Get a stream for writing to a file:// URI
2164

    
2165
        public static Stream getWritableUriStream(Uri uri)
2166
        {
2167
            FileWebRequest request = (FileWebRequest)WebRequest.CreateDefault(uri);
2168
            request.Method = "POST";
2169
            return request.GetRequestStream();
2170
        }
2171
    }
2172

    
2173
    ///
2174
    /// A sample XmlResolver. In the case of a URI ending with ".txt", it returns the
2175
    /// URI itself, wrapped as an XML document. In the case of the URI "empty.xslt", it returns an empty
2176
    /// stylesheet. In all other cases, it returns null, which has the effect of delegating
2177
    /// processing to the standard XmlResolver.
2178
    ///
2179

    
2180
    public class UserXmlResolver : XmlUrlResolver
2181
    {
2182

    
2183
        public String Message = null;
2184

    
2185
        public override object GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
2186
        {
2187
            if (Message != null)
2188
            {
2189
                Console.WriteLine(Message + absoluteUri + " (role=" + role + ")");
2190
            }
2191

    
2192
            if (absoluteUri.ToString().EndsWith(".txt"))
2193
            {
2194
                MemoryStream ms = new MemoryStream();
2195
                StreamWriter tw = new StreamWriter(ms);
2196
                tw.Write("<uri>");
2197
                tw.Write(absoluteUri);
2198
                tw.Write("</uri>");
2199
                tw.Flush();
2200
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2201
            }
2202
            if (absoluteUri.ToString().EndsWith("empty.xslt"))
2203
            {
2204
                String ss = "<transform xmlns='http://www.w3.org/1999/XSL/Transform' version='2.0'/>";
2205
                MemoryStream ms = new MemoryStream();
2206
                StreamWriter tw = new StreamWriter(ms);
2207
                tw.Write(ss);
2208
                tw.Flush();
2209
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2210
            }
2211
            else
2212
            {
2213
                return null;
2214
            }
2215
        }
2216
    }
2217

    
2218
    public class UserResultDocumentHandler : IResultDocumentHandler
2219
    {
2220

    
2221
        private Hashtable results;
2222

    
2223
        public UserResultDocumentHandler(Hashtable table)
2224
        {
2225
            this.results = table;
2226
        }
2227

    
2228
        public XmlDestination HandleResultDocument(string href, Uri baseUri)
2229
        {
2230
            DomDestination destination = new DomDestination();
2231
            results[href] = destination;
2232
            return destination;
2233
        }
2234

    
2235
    }
2236
}
2237

    
2238

    
2239
//
2240
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
2241
// you may not use this file except in compliance with the License. You may obtain a copy of the
2242
// License at http://www.mozilla.org/MPL/
2243
//
2244
// Software distributed under the License is distributed on an "AS IS" basis,
2245
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
2246
// See the License for the specific language governing rights and limitations under the License.
2247
//
2248
// The Original Code is: all this file.
2249
//
2250
// The Initial Developer of the Original Code is Michael H. Kay.
2251
//
2252
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
2253
//
2254
// Contributor(s): none.
2255
//
(2-2/5)