Project

Profile

Help

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

he / latest9.4 / hen / csource / samples / ExamplesPE.cs @ c3c84ba2

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

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

    
24

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

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

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

    
75
            String samplesPath = null;
76
            Uri samplesDir;
77

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

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

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

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

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

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

    
198
    ///<summary>
199
    /// Each of the example programs is implemented as a subclass of the abstract class Example
200
    ///</summary> 
201

    
202

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

    
215
    /// <summary>
216
    /// XPath expression selecting from a source document supplied as a URI
217
    /// </summary>
218

    
219
    public class XPathSimple : Example
220
    {
221

    
222
        public override String testName
223
        {
224
            get { return "XPathSimple"; }
225
        }
226

    
227
        /// <summary>
228
        /// Run a transformation: simplest possible script
229
        /// </summary>
230

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

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

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

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

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

    
254
    /// <summary>
255
    /// XPath expression using variables (and no source document)
256
    /// </summary>
257

    
258
    public class XPathVariables : Example
259
    {
260

    
261
        public override String testName
262
        {
263
            get { return "XPathVariables"; }
264
        }
265

    
266
        /// <summary>
267
        /// Run a transformation: simplest possible script
268
        /// </summary>
269

    
270
        public override void run(Uri samplesDir)
271
        {
272
            // Create a Processor instance.
273
            Processor processor = new Processor();
274

    
275
            // Create the XPath expression.
276
            XPathCompiler compiler = processor.NewXPathCompiler();
277
            compiler.DeclareVariable(new QName("", "a"));
278
            compiler.DeclareVariable(new QName("", "b"));
279
            XPathSelector selector = compiler.Compile("$a + $b").Load();
280

    
281
            // Set the values of the variables
282
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(2));
283
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue(3));
284

    
285
            // Evaluate the XPath expression
286
            Console.WriteLine(selector.EvaluateSingle().ToString());
287
        }
288
    }
289

    
290
    /// <summary>
291
    /// XPath expression using variables without explicit declaration
292
    /// </summary>
293

    
294
    public class XPathUndeclaredVariables : Example
295
    {
296

    
297
        public override String testName
298
        {
299
            get { return "XPathUndeclaredVariables"; }
300
        }
301

    
302
        /// <summary>
303
        /// Execute an XPath expression containing undeclared variables
304
        /// </summary>
305

    
306
        public override void run(Uri samplesDir)
307
        {
308
            // Create a Processor instance.
309
            Processor processor = new Processor();
310

    
311
            // Create the XPath expression.
312
            XPathCompiler compiler = processor.NewXPathCompiler();
313
            compiler.AllowUndeclaredVariables = true;
314
            XPathExecutable expression = compiler.Compile("$a + $b");
315
            XPathSelector selector = expression.Load();
316

    
317
            // Set the values of the variables
318
            IEnumerator vars = expression.EnumerateExternalVariables();
319
            while (vars.MoveNext())
320
            {
321
                selector.SetVariable((QName)vars.Current, new XdmAtomicValue(10));
322
            }
323

    
324
            // Evaluate the XPath expression
325
            Console.WriteLine(selector.EvaluateSingle().ToString());
326
        }
327
    }
328

    
329
    /// <summary>
330
    /// XPath expression throwing a static error
331
    /// </summary>
332

    
333
    public class XPathWithStaticError : Example
334
    {
335

    
336
        public override String testName
337
        {
338
            get { return "XPathWithStaticError"; }
339
        }
340

    
341
        /// <summary>
342
        /// Execute an XPath expression that throws a dynamic error, and catch the error
343
        /// </summary>
344

    
345
        public override void run(Uri samplesDir)
346
        {
347
            // Create a Processor instance.
348
            Processor processor = new Processor();
349

    
350
            // Create the XPath expression.
351
            XPathCompiler compiler = processor.NewXPathCompiler();
352
            compiler.AllowUndeclaredVariables = true;
353
            XPathExecutable expression = compiler.Compile("1 + unknown()");
354
            XPathSelector selector = expression.Load();
355

    
356
            // Evaluate the XPath expression
357
            Console.WriteLine(selector.EvaluateSingle().ToString());
358
        }
359
    }
360

    
361
    /// <summary>
362
    /// XPath expression throwing a dynamic error
363
    /// </summary>
364

    
365
    public class XPathWithDynamicError : Example
366
    {
367

    
368
        public override String testName
369
        {
370
            get { return "XPathWithDynamicError"; }
371
        }
372

    
373
        /// <summary>
374
        /// Execute an XPath expression that throws a dynamic error
375
        /// </summary>
376

    
377
        public override void run(Uri samplesDir)
378
        {
379
            // Create a Processor instance.
380
            Processor processor = new Processor();
381

    
382
            // Create the XPath expression.
383
            XPathCompiler compiler = processor.NewXPathCompiler();
384
            compiler.AllowUndeclaredVariables = true;
385
            XPathExecutable expression = compiler.Compile("$a gt $b");
386
            XPathSelector selector = expression.Load();
387

    
388
            // Set the values of the variables
389
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(10));
390
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue("Paris"));
391

    
392
            // Evaluate the XPath expression
393
            Console.WriteLine(selector.EvaluateSingle().ToString());
394
        }
395
    }
396

    
397
    /// <summary>
398
    /// XSLT 2.0 transformation with source document and stylesheet supplied as URIs
399
    /// </summary>
400

    
401
    public class XsltSimple1 : Example
402
    {
403

    
404
        public override String testName
405
        {
406
            get { return "XsltSimple1"; }
407
        }
408

    
409
        /// <summary>
410
        /// Run a transformation: simplest possible script
411
        /// </summary>
412

    
413
        public override void run(Uri samplesDir)
414
        {
415
            // Create a Processor instance.
416
            Processor processor = new Processor();
417

    
418
            // Load the source document
419
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
420

    
421
            // Create a transformer for the stylesheet.
422
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/books.xsl")).Load();
423

    
424
            // Set the root node of the source document to be the initial context node
425
            transformer.InitialContextNode = input;
426

    
427
            // Create a serializer, with output to the standard output stream
428
            Serializer serializer = new Serializer();
429
            serializer.SetOutputWriter(Console.Out);
430

    
431
            // Transform the source XML and serialize the result document
432
            transformer.Run(serializer);
433
        }
434
    }
435

    
436
    /// <summary>
437
    /// Run a transformation, sending the serialized output to a file
438
    /// </summary>
439

    
440
    public class XsltSimple2 : Example
441
    {
442

    
443
        public override String testName
444
        {
445
            get { return "XsltSimple2"; }
446
        }
447

    
448
        /// <summary>
449
        /// Run the transformation, sending the serialized output to a file
450
        /// </summary>
451

    
452

    
453
        public override void run(Uri samplesDir)
454
        {
455
            // Create a Processor instance.
456
            Processor processor = new Processor();
457

    
458
            // Load the source document
459
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
460

    
461
            // Create a transformer for the stylesheet.
462
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/identity.xsl")).Load();
463

    
464
            // Set the root node of the source document to be the initial context node
465
            transformer.InitialContextNode = input;
466

    
467
            // Create a serializer
468
            String outfile = "OutputFromXsltSimple2.xml";
469
            Serializer serializer = new Serializer();
470
            serializer.SetOutputStream(new FileStream(outfile, FileMode.Create, FileAccess.Write));
471

    
472
            // Transform the source XML to System.out.
473
            transformer.Run(serializer);
474

    
475
            Console.WriteLine("\nOutput written to " + outfile + "\n");
476
        }
477
    }
478

    
479
    /// <summary>
480
    /// XSLT 2.0 transformation with source document and stylesheet supplied as URIs
481
    /// </summary>
482

    
483
    public class XsltSimple3 : Example
484
    {
485

    
486
        public override String testName
487
        {
488
            get { return "XsltSimple3"; }
489
        }
490

    
491
        /// <summary>
492
        /// Run a transformation: supply input as a file
493
        /// </summary>
494

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

    
505
            // Create a Processor instance.
506
            Processor processor = new Processor();
507

    
508
            // Load the source document
509

    
510
            DocumentBuilder builder = processor.NewDocumentBuilder();
511
            builder.BaseUri = new Uri(samplesDir, "data/books.xml");
512

    
513
            XdmNode input = builder.Build(File.OpenRead(sourceFile));
514

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

    
520
            // Set the root node of the source document to be the initial context node
521
            transformer.InitialContextNode = input;
522

    
523
            // Create a serializer, with output to the standard output stream
524
            Serializer serializer = new Serializer();
525
            serializer.SetOutputWriter(Console.Out);
526

    
527
            // Transform the source XML and serialize the result document
528
            transformer.Run(serializer);
529
        }
530
    }
531

    
532

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

    
537
    public class XsltStripSpace : Example
538
    {
539

    
540
        public override String testName
541
        {
542
            get { return "XsltStripSpace"; }
543
        }
544

    
545
        /// <summary>
546
        /// Run a transformation: simplest possible script
547
        /// </summary>
548

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

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

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

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

    
574
            XsltCompiler compiler = processor.NewXsltCompiler();
575
            compiler.BaseUri = samplesDir;
576
            XsltTransformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load();
577

    
578
            // Set the root node of the source document to be the initial context node
579
            transformer.InitialContextNode = input;
580

    
581
            // Create a serializer
582
            Serializer serializer = new Serializer();
583
            serializer.SetOutputWriter(Console.Out);
584

    
585
            // Transform the source XML to System.out.
586
            transformer.Run(serializer);
587
        }
588
    }
589

    
590

    
591
    /// <summary>
592
    /// Run a transformation, compiling the stylesheet once and using it to transform two different source documents
593
    /// </summary>
594

    
595
    public class XsltReuseExecutable : Example
596
    {
597

    
598
        public override String testName
599
        {
600
            get { return "XsltReuseExecutable"; }
601
        }
602

    
603
        /// <summary>
604
        /// Show that a stylesheet can be compiled once (into an XsltExecutable) and run many times
605
        /// </summary>
606
        /// <param name="fileNames">
607
        /// 1. first source document
608
        /// 2. second source document
609
        /// 3. stylesheet used to transform both documents
610
        /// </param>
611

    
612
        public override void run(Uri samplesDir)
613
        {
614
            // Create a Processor instance.
615
            Processor processor = new Processor();
616

    
617
            // Create a compiled stylesheet
618
            XsltExecutable templates = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
619

    
620
            // Note: we could actually use the same XsltTransformer in this case.
621
            // But in principle, the two transformations could be done in parallel in separate threads.
622

    
623
            String sourceFile1 = "data/books.xml";
624
            String sourceFile2 = "data/othello.xml";
625

    
626
            // Do the first transformation
627
            Console.WriteLine("\n\n----- transform of " + sourceFile1 + " -----");
628
            XsltTransformer transformer1 = templates.Load();
629
            transformer1.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile1));
630
            transformer1.Run(new Serializer());     // default destination is Console.Out
631

    
632
            // Do the second transformation
633
            Console.WriteLine("\n\n----- transform of " + sourceFile2 + " -----");
634
            XsltTransformer transformer2 = templates.Load();
635
            transformer2.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile2));
636
            transformer2.Run(new Serializer());     // default destination is Console.Out    
637
        }
638
    }
639

    
640
    /// <summary>
641
    /// Show that the XsltTransformer is serially reusable; run a transformation twice using the same stylesheet
642
    /// and the same input document but with different parameters.
643
    /// </summary>
644

    
645
    public class XsltReuseTransformer : Example
646
    {
647

    
648
        public override String testName
649
        {
650
            get { return "XsltReuseTransformer"; }
651
        }
652

    
653
        /// <summary>
654
        /// Show that the XsltTransformer is serially reusable (we run it twice with different parameter settings)
655
        /// </summary>
656

    
657
        public override void run(Uri samplesDir)
658
        {
659
            // Create a Processor instance.
660
            Processor processor = new Processor();
661

    
662
            // Load the source document, building a tree
663
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
664

    
665
            // Compile the stylesheet
666
            XsltExecutable exec = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
667

    
668
            // Create a transformer 
669
            XsltTransformer transformer = exec.Load();
670

    
671
            // Run it once        
672
            transformer.SetParameter(new QName("", "", "include-attributes"), new XdmAtomicValue(false));
673
            transformer.InitialContextNode = input;
674
            XdmDestination results = new XdmDestination();
675
            transformer.Run(results);
676
            Console.WriteLine("1: " + results.XdmNode.OuterXml);
677

    
678
            // Run it again        
679
            transformer.SetParameter(new QName("", "", "include-attributes"), new XdmAtomicValue(true));
680
            transformer.InitialContextNode = input;
681
            results.Reset();
682
            transformer.Run(results);
683
            Console.WriteLine("2: " + results.XdmNode.OuterXml);
684
        }
685
    }
686

    
687
    /// <summary>
688
    /// Run a sequence of transformations in a pipeline, each one acting as a filter
689
    /// </summary>
690

    
691
    public class XsltFilterChain : Example
692
    {
693

    
694
        public override String testName
695
        {
696
            get { return "XsltFilterChain"; }
697
        }
698

    
699
        /// <summary>
700
        /// Run the test
701
        /// </summary>
702

    
703
        public override void run(Uri samplesDir)
704
        {
705
            // Create a Processor instance.
706
            Processor processor = new Processor();
707

    
708
            // Load the source document
709
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
710

    
711
            // Create a compiler
712
            XsltCompiler compiler = processor.NewXsltCompiler();
713

    
714
            // Compile all three stylesheets
715
            XsltTransformer transformer1 = compiler.Compile(new Uri(samplesDir, "styles/identity.xsl")).Load();
716
            XsltTransformer transformer2 = compiler.Compile(new Uri(samplesDir, "styles/books.xsl")).Load();
717
            XsltTransformer transformer3 = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
718

    
719
            // Now run them in series
720
            transformer1.InitialContextNode = input;
721
            XdmDestination results1 = new XdmDestination();
722
            transformer1.Run(results1);
723
            //Console.WriteLine("After phase 1:");
724
            //Console.WriteLine(results1.XdmNode.OuterXml);
725

    
726
            transformer2.InitialContextNode = results1.XdmNode;
727
            XdmDestination results2 = new XdmDestination();
728
            transformer2.Run(results2);
729
            //Console.WriteLine("After phase 2:");
730
            //Console.WriteLine(results2.XdmNode.OuterXml);
731

    
732
            transformer3.InitialContextNode = results2.XdmNode;
733
            //TextWriterDestination results3 = new TextWriterDestination(new XmlTextWriter(Console.Out));
734
            XdmDestination results3 = new XdmDestination();
735
            transformer3.Run(results3);
736
            Console.WriteLine("After phase 3:");
737
            Console.WriteLine(results3.XdmNode.OuterXml);
738
        }
739
    }
740

    
741
    /// <summary>
742
    /// Transform from an XDM tree to an XDM tree
743
    /// </summary>
744

    
745
    public class XsltXdmToXdm : Example
746
    {
747

    
748
        public override String testName
749
        {
750
            get { return "XsltXdmToXdm"; }
751
        }
752

    
753
        /// <summary>
754
        /// Transform from an XDM tree to an XDM tree
755
        /// </summary>
756

    
757
        public override void run(Uri samplesDir)
758
        {
759
            // Create a Processor instance.
760
            Processor processor = new Processor();
761

    
762
            // Load the source document
763
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
764

    
765
            // Create a compiler
766
            XsltCompiler compiler = processor.NewXsltCompiler();
767

    
768
            // Compile the stylesheet
769
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
770

    
771
            // Run the transformation
772
            transformer.InitialContextNode = input;
773
            XdmDestination result = new XdmDestination();
774
            transformer.Run(result);
775

    
776
            // Serialize the result so we can see that it worked
777
            StringWriter sw = new StringWriter();
778
            result.XdmNode.WriteTo(new XmlTextWriter(sw));
779
            Console.WriteLine(sw.ToString());
780

    
781
            // Note: we don't do 
782
            //   result.XdmNode.WriteTo(new XmlTextWriter(Console.Out));
783
            // because that results in the Console.out stream being closed, 
784
            // with subsequent attempts to write to it being rejected.
785
        }
786
    }
787

    
788
    /// <summary>
789
    /// Run an XSLT transformation from an Xdm tree, starting at a node that is not the document node
790
    /// </summary>
791

    
792
    public class XsltXdmElementToXdm : Example
793
    {
794

    
795
        public override String testName
796
        {
797
            get { return "XsltXdmElementToXdm"; }
798
        }
799

    
800
        /// <summary>
801
        /// Run an XSLT transformation from an Xdm tree, starting at a node that is not the document node
802
        /// </summary>
803
        /// <param name="fileNames">
804
        /// 1. The source document
805
        /// 2. The stylesheet
806
        /// </param>
807

    
808
        public override void run(Uri samplesDir)
809
        {
810
            // Create a Processor instance.
811
            Processor processor = new Processor();
812

    
813
            // Load the source document
814
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
815

    
816
            // Navigate to the first grandchild
817
            XPathSelector eval = processor.NewXPathCompiler().Compile("/PLAY/FM[1]").Load();
818
            eval.ContextItem = input;
819
            input = (XdmNode)eval.EvaluateSingle();
820

    
821
            // Create an XSLT compiler
822
            XsltCompiler compiler = processor.NewXsltCompiler();
823

    
824
            // Compile the stylesheet
825
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
826

    
827
            // Run the transformation
828
            transformer.InitialContextNode = input;
829
            XdmDestination result = new XdmDestination();
830
            transformer.Run(result);
831

    
832
            // Serialize the result so we can see that it worked
833
            Console.WriteLine(result.XdmNode.OuterXml);
834
        }
835
    }
836

    
837
    /// <summary>
838
    /// Run a transformation from a DOM (System.Xml.Document) input to a DOM output
839
    /// </summary>
840

    
841
    public class XsltDomToDom : Example
842
    {
843

    
844
        public override String testName
845
        {
846
            get { return "XsltDomToDom"; }
847
        }
848

    
849
        /// <summary>
850
        /// Run a transformation from a DOM (System.Xml.Document) input to a DOM output
851
        /// </summary>
852

    
853
        public override void run(Uri samplesDir)
854
        {
855

    
856
            // Create a Processor instance.
857
            Processor processor = new Processor();
858

    
859
            // Load the source document (in practice, it would already exist as a DOM)
860
            XmlDocument doc = new XmlDocument();
861
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/othello.xml"));
862
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
863

    
864
            // Create a compiler
865
            XsltCompiler compiler = processor.NewXsltCompiler();
866

    
867
            // Compile the stylesheet
868
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
869

    
870
            // Run the transformation
871
            transformer.InitialContextNode = input;
872
            DomDestination result = new DomDestination();
873
            transformer.Run(result);
874

    
875
            // Serialize the result so we can see that it worked
876
            Console.WriteLine(result.XmlDocument.OuterXml);
877
        }
878
    }
879

    
880

    
881
    /// <summary>
882
    /// Run a transformation driven by an xml-stylesheet processing instruction in the source document
883
    /// </summary>
884

    
885
    public class XsltProcessingInstruction : Example
886
    {
887

    
888
        public override string testName
889
        {
890
            get { return "XsltProcessingInstruction"; }
891
        }
892

    
893
        /// <summary>
894
        /// Run a transformation driven by an xml-stylesheet processing instruction in the source document
895
        /// </summary>
896
        /// <param name="fileNames">
897
        /// 1. The source document
898
        /// </param>
899

    
900
        public override void run(Uri samplesDir)
901
        {
902
            // Create a Processor instance.
903
            Processor processor = new Processor();
904
            XsltExecutable exec;
905

    
906
            // Load the source document
907
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
908
            //Console.WriteLine("=============== source document ===============");
909
            //Console.WriteLine(input.OuterXml);
910
            //Console.WriteLine("=========== end of source document ============");
911

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

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

    
918
            XPathSelector eval = processor.NewXPathCompiler().Compile(path).Load();
919
            eval.ContextItem = input;
920
            XdmAtomicValue hrefval = (XdmAtomicValue)eval.EvaluateSingle();
921
            String href = (hrefval == null ? null : hrefval.ToString());
922

    
923
            if (href == null || href == "")
924
            {
925
                Console.WriteLine("No suitable xml-stylesheet processing instruction found");
926
                return;
927

    
928
            }
929
            else if (href[0] == '#')
930
            {
931

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

    
934
                Console.WriteLine("Locating embedded stylesheet with href = " + href);
935
                String idpath = "id('" + href.Substring(1) + "')";
936
                eval = processor.NewXPathCompiler().Compile(idpath).Load();
937
                eval.ContextItem = input;
938
                XdmNode node = (XdmNode)eval.EvaluateSingle();
939
                if (node == null)
940
                {
941
                    Console.WriteLine("No element found with ID " + href.Substring(1));
942
                    return;
943
                }
944
                exec = processor.NewXsltCompiler().Compile(node);
945

    
946
            }
947
            else
948
            {
949

    
950
                // The stylesheet is in an external document
951

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

    
954
                // Fetch and compile the referenced stylesheet
955
                exec = processor.NewXsltCompiler().Compile(new Uri(input.BaseUri, href.ToString()));
956
            }
957

    
958
            // Create a transformer 
959
            XsltTransformer transformer = exec.Load();
960

    
961
            // Run it       
962
            transformer.InitialContextNode = input;
963
            XdmDestination results = new XdmDestination();
964
            transformer.Run(results);
965
            Console.WriteLine("1: " + results.XdmNode.OuterXml);
966

    
967
        }
968
    }
969

    
970
    /// <summary>
971
    /// Run an XSLT transformation setting serialization properties from the calling application
972
    /// </summary>
973

    
974
    public class XsltSettingOutputProperties : Example
975
    {
976

    
977
        public override string testName
978
        {
979
            get { return "XsltSettingOutputProperties"; }
980
        }
981

    
982
        /// <summary>
983
        /// Run an XSLT transformation setting serialization properties from the calling application
984
        /// </summary>
985

    
986
        public override void run(Uri samplesDir)
987
        {
988
            // Create a Processor instance.
989
            Processor processor = new Processor();
990

    
991
            // Load the source document
992
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
993

    
994
            // Create a transformer for the stylesheet.
995
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
996

    
997
            // Set the root node of the source document to be the initial context node
998
            transformer.InitialContextNode = input;
999

    
1000
            // Create a serializer, with output to the standard output stream
1001
            Serializer serializer = new Serializer();
1002
            serializer.SetOutputProperty(Serializer.METHOD, "xml");
1003
            serializer.SetOutputProperty(Serializer.INDENT, "no");
1004
            serializer.SetOutputWriter(Console.Out);
1005

    
1006
            // Transform the source XML and serialize the result document
1007
            transformer.Run(serializer);
1008
        }
1009

    
1010
    }
1011

    
1012
    /// <summary>
1013
    /// Run an XSLT transformation making use of an XmlResolver to resolve URIs at document build time, at stylesheet compile time 
1014
    /// and at transformation run-time
1015
    /// </summary>
1016

    
1017
    public class XsltUsingSourceResolver : Example
1018
    {
1019

    
1020
        public override string testName
1021
        {
1022
            get { return "XsltUsingSourceResolver"; }
1023
        }
1024

    
1025
        /// <summary>
1026
        /// Run an XSLT transformation making use of an XmlResolver to resolve URIs both at compile time and at run-time
1027
        /// </summary>
1028

    
1029
        public override void run(Uri samplesDir)
1030
        {
1031

    
1032
            // Create a Processor instance.
1033
            Processor processor = new Processor();
1034

    
1035
            // Load the source document
1036
            DocumentBuilder builder = processor.NewDocumentBuilder();
1037
            UserXmlResolver buildTimeResolver = new UserXmlResolver();
1038
            buildTimeResolver.Message = "** Calling build-time XmlResolver: ";
1039
            builder.XmlResolver = buildTimeResolver;
1040
            builder.BaseUri = samplesDir;
1041

    
1042
            String doc = "<!DOCTYPE doc [<!ENTITY e SYSTEM 'flamingo.txt'>]><doc>&e;</doc>";
1043
            MemoryStream ms = new MemoryStream();
1044
            StreamWriter tw = new StreamWriter(ms);
1045
            tw.Write(doc);
1046
            tw.Flush();
1047
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1048
            XdmNode input = builder.Build(instr);
1049

    
1050
            // Create a transformer for the stylesheet.
1051
            String stylesheet =
1052
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>" +
1053
                "<xsl:import href='empty.xslt'/>" +
1054
                "<xsl:template match='/'>" +
1055
                "<out note=\"{doc('heron.txt')}\" ><xsl:copy-of select='.'/></out>" +
1056
                "</xsl:template>" +
1057
                "</xsl:stylesheet>";
1058

    
1059
            XsltCompiler compiler = processor.NewXsltCompiler();
1060
            UserXmlResolver compileTimeResolver = new UserXmlResolver();
1061
            compileTimeResolver.Message = "** Calling compile-time XmlResolver: ";
1062
            compiler.XmlResolver = compileTimeResolver;
1063
            compiler.BaseUri = samplesDir;
1064
            XsltTransformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load();
1065

    
1066
            // Set the root node of the source document to be the initial context node
1067
            transformer.InitialContextNode = input;
1068

    
1069
            // Set the user-written XmlResolver
1070
            UserXmlResolver runTimeResolver = new UserXmlResolver();
1071
            runTimeResolver.Message = "** Calling transformation-time XmlResolver: ";
1072
            transformer.InputXmlResolver = runTimeResolver;
1073

    
1074
            // Create a serializer
1075
            Serializer serializer = new Serializer();
1076
            serializer.SetOutputWriter(Console.Out);
1077

    
1078
            // Transform the source XML to System.out.
1079
            transformer.Run(serializer);
1080

    
1081
        }
1082
    }
1083

    
1084
    /// <summary>
1085
    /// Run an XSLT transformation displaying compile-time errors to the console
1086
    /// </summary>
1087

    
1088
    public class XsltDisplayingErrors : Example
1089
    {
1090

    
1091
        public override string testName
1092
        {
1093
            get { return "XsltDisplayingErrors"; }
1094
        }
1095

    
1096
        /// <summary>
1097
        /// Run an XSLT transformation displaying compile-time errors to the console
1098
        /// </summary>
1099

    
1100
        public override void run(Uri samplesDir)
1101
        {
1102
            // Create a Processor instance.
1103
            Processor processor = new Processor();
1104

    
1105
            // Create the XSLT Compiler
1106
            XsltCompiler compiler = processor.NewXsltCompiler();
1107

    
1108

    
1109
            // Define a stylesheet containing errors
1110
            String stylesheet =
1111
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
1112
                "<xsl:template name='eee:template'>\n" +
1113
                "  <xsl:value-of select='32'/>\n" +
1114
                "</xsl:template>\n" +
1115
                "<xsl:template name='main'>\n" +
1116
                "  <xsl:value-of select='$var'/>\n" +
1117
                "</xsl:template>\n" +
1118
                "</xsl:stylesheet>";
1119

    
1120

    
1121
            // Attempt to compile the stylesheet and display the errors
1122
            try
1123
            {
1124
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1125
                compiler.Compile(new XmlTextReader(new StringReader(stylesheet)));
1126
                Console.WriteLine("Stylesheet compilation succeeded");
1127
            }
1128
            catch (Exception)
1129
            {
1130
                Console.WriteLine("Stylesheet compilation failed");
1131
            }
1132

    
1133

    
1134
        }
1135
    }
1136

    
1137
    /// <summary>
1138
    /// Run an XSLT transformation capturing compile-time errors within the application
1139
    /// </summary>
1140

    
1141
    public class XsltCapturingErrors : Example
1142
    {
1143

    
1144
        public override string testName
1145
        {
1146
            get { return "XsltCapturingErrors"; }
1147
        }
1148

    
1149
        /// <summary>
1150
        /// Run an XSLT transformation capturing compile-time errors within the application
1151
        /// </summary>
1152

    
1153
        public override void run(Uri samplesDir)
1154
        {
1155
            // Create a Processor instance.
1156
            Processor processor = new Processor();
1157

    
1158
            // Create the XSLT Compiler
1159
            XsltCompiler compiler = processor.NewXsltCompiler();
1160

    
1161
            // Create a list to hold the error information
1162
            compiler.ErrorList = new ArrayList();
1163

    
1164
            // Define a stylesheet containing errors
1165
            String stylesheet =
1166
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
1167
                "<xsl:template name='fff:template'>\n" +
1168
                "  <xsl:value-of select='32'/>\n" +
1169
                "</xsl:template>\n" +
1170
                "<xsl:template name='main'>\n" +
1171
                "  <xsl:value-of select='$var'/>\n" +
1172
                "</xsl:template>\n" +
1173
                "</xsl:stylesheet>";
1174

    
1175

    
1176
            // Attempt to compile the stylesheet and display the errors
1177
            try
1178
            {
1179
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1180
                compiler.Compile(new StringReader(stylesheet));
1181
                Console.WriteLine("Stylesheet compilation succeeded");
1182
            }
1183
            catch (Exception)
1184
            {
1185
                Console.WriteLine("Stylesheet compilation failed with " + compiler.ErrorList.Count + " errors");
1186
                foreach (StaticError error in compiler.ErrorList)
1187
                {
1188
                    Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
1189
                }
1190
            }
1191
        }
1192
    }
1193

    
1194
    /// <summary>
1195
    /// Run an XSLT transformation capturing run-time messages within the application
1196
    /// </summary>
1197

    
1198
    public class XsltCapturingMessages : Example
1199
    {
1200

    
1201
        public override string testName
1202
        {
1203
            get { return "XsltCapturingMessages"; }
1204
        }
1205

    
1206
        /// <summary>
1207
        /// Run an XSLT transformation capturing run-time messages within the application
1208
        /// </summary>
1209

    
1210
        public override void run(Uri samplesDir)
1211
        {
1212

    
1213
            // Create a Processor instance.
1214
            Processor processor = new Processor();
1215

    
1216
            // Create the XSLT Compiler
1217
            XsltCompiler compiler = processor.NewXsltCompiler();
1218

    
1219
            // Define a stylesheet that generates messages
1220
            String stylesheet =
1221
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1222
                "<xsl:template name='main'>\n" +
1223
                "  <xsl:message><a>starting</a></xsl:message>\n" +
1224
                "  <out><xsl:value-of select='current-date()'/></out>\n" +
1225
                "  <xsl:message><a>finishing</a></xsl:message>\n" +
1226
                "</xsl:template>\n" +
1227
                "</xsl:stylesheet>";
1228

    
1229
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1230
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1231

    
1232

    
1233
            // Create a transformer for the stylesheet.
1234
            XsltTransformer transformer = exec.Load();
1235

    
1236
            // Set the name of the initial template
1237
            transformer.InitialTemplate = new QName("", "main");
1238

    
1239
            // Create a Listener to which messages will be written
1240
            transformer.MessageListener = new UserMessageListener();
1241

    
1242
            // Create a serializer
1243
            Serializer serializer = new Serializer();
1244
            serializer.SetOutputWriter(Console.Out);
1245

    
1246
            // Transform the source XML to System.out.
1247
            transformer.Run(serializer);
1248
        }
1249

    
1250
    }
1251

    
1252
    ///
1253
    /// Example user-written message listener
1254
    ///
1255

    
1256
    public class UserMessageListener : IMessageListener
1257
    {
1258

    
1259
        public void Message(XdmNode content, bool terminate, IXmlLocation location)
1260
        {
1261
            Console.Out.WriteLine("MESSAGE terminate=" + (terminate ? "yes" : "no") + " at " + DateTime.Now);
1262
            Console.Out.WriteLine("From instruction at line " + location.LineNumber +
1263
                    " of " + location.BaseUri);
1264
            Console.Out.WriteLine(">>" + content.StringValue);
1265
        }
1266
    }
1267

    
1268
    /// <summary>
1269
    /// Run an XSLT transformation showing source line numbers
1270
    /// </summary>
1271

    
1272
    public class XsltShowingLineNumbers : Example
1273
    {
1274

    
1275
        public override string testName
1276
        {
1277
            get { return "XsltShowingLineNumbers"; }
1278
        }
1279

    
1280
        /// <summary>
1281
        /// Run an XSLT transformation capturing run-time messages within the application
1282
        /// </summary>
1283

    
1284
        public override void run(Uri samplesDir)
1285
        {
1286

    
1287
            // Create a Processor instance.
1288
            Processor processor = new Processor();
1289

    
1290
            // Ask for the JAXP parser to be used (or not to be used, if false)
1291
            processor.SetProperty("http://saxon.sf.net/feature/preferJaxpParser", "false");
1292

    
1293
            // Load the source document
1294
            DocumentBuilder builder = processor.NewDocumentBuilder();
1295
            builder.IsLineNumbering = true;
1296
            XdmNode input = builder.Build(new Uri(samplesDir, "data/othello.xml"));
1297

    
1298
            // Create the XSLT Compiler
1299
            XsltCompiler compiler = processor.NewXsltCompiler();
1300

    
1301
            // Define a stylesheet that shows line numbers of source elements
1302
            String stylesheet =
1303
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0' xmlns:saxon='http://saxon.sf.net/'>\n" +
1304
                "<xsl:template match='/'>\n" +
1305
                "<out>\n" +
1306
                "  <xsl:for-each select='//ACT'>\n" +
1307
                "  <out><xsl:value-of select='saxon:line-number(.)'/></out>\n" +
1308
                "  </xsl:for-each>\n" +
1309
                "</out>\n" +
1310
                "</xsl:template>\n" +
1311
                "</xsl:stylesheet>";
1312

    
1313
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1314
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1315

    
1316

    
1317
            // Create a transformer for the stylesheet.
1318
            XsltTransformer transformer = exec.Load();
1319

    
1320
            // Set the root node of the source document to be the initial context node
1321
            transformer.InitialContextNode = input;
1322

    
1323
            // Create a serializer
1324
            Serializer serializer = new Serializer();
1325
            serializer.SetOutputWriter(Console.Out);
1326

    
1327
            // Transform the source XML to System.out.
1328
            transformer.Run(serializer);
1329
        }
1330

    
1331
    }
1332

    
1333
    /// <summary>
1334
    /// Run an XSLT transformation producing multiple output documents
1335
    /// </summary>
1336

    
1337
    public class XsltMultipleOutput : Example
1338
    {
1339

    
1340
        public override string testName
1341
        {
1342
            get { return "XsltMultipleOutput"; }
1343
        }
1344

    
1345
        /// <summary>
1346
        /// Run an XSLT transformation producing multiple output documents
1347
        /// </summary>
1348

    
1349
        public override void run(Uri samplesDir)
1350
        {
1351
            // Create a Processor instance.
1352
            Processor processor = new Processor();
1353
            processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
1354

    
1355
            // Load the source document
1356
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1357

    
1358
            // Create a transformer for the stylesheet.
1359
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/play.xsl")).Load();
1360

    
1361
            // Set the root node of the source document to be the initial context node
1362
            transformer.InitialContextNode = input;
1363

    
1364
            // Set the required stylesheet parameter
1365
            transformer.SetParameter(new QName("", "", "dir"), new XdmAtomicValue(samplesDir.ToString() + "play"));
1366

    
1367
            // Create a serializer
1368
            Serializer serializer = new Serializer();
1369
            serializer.SetOutputWriter(Console.Out);
1370

    
1371
            // Transform the source XML to System.out.
1372
            transformer.Run(serializer);
1373

    
1374
        }
1375

    
1376
    }
1377

    
1378

    
1379
    /// <summary>
1380
    /// Run an XSLT transformation using the id() function, with DTD validation
1381
    /// </summary>
1382

    
1383
    public class XsltUsingIdFunction : Example
1384
    {
1385

    
1386
        public override string testName
1387
        {
1388
            get { return "XsltUsingIdFunction"; }
1389
        }
1390

    
1391
        /// <summary>
1392
        /// Run an XSLT transformation using the id() function, with DTD validation
1393
        /// </summary>
1394

    
1395
        public override void run(Uri samplesDir)
1396
        {
1397
            // Create a Processor instance
1398
            Processor processor = new Processor();
1399

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

    
1404
            String doc = "<!DOCTYPE table [" +
1405
                "<!ELEMENT table (row*)>" +
1406
                "<!ELEMENT row EMPTY>" +
1407
                "<!ATTLIST row xml:id ID #REQUIRED>" +
1408
                "<!ATTLIST row value CDATA #REQUIRED>]>" +
1409
                "<table><row xml:id='A123' value='green'/><row xml:id='Z789' value='blue'/></table>";
1410

    
1411
            DocumentBuilder builder = processor.NewDocumentBuilder();
1412
            builder.DtdValidation = true;
1413
            builder.BaseUri = samplesDir;
1414
            MemoryStream ms = new MemoryStream();
1415
            StreamWriter tw = new StreamWriter(ms);
1416
            tw.Write(doc);
1417
            tw.Flush();
1418
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1419
            XdmNode input = builder.Build(instr);
1420

    
1421
            // Define a stylesheet that uses the id() function
1422
            String stylesheet =
1423
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1424
                "<xsl:template match='/'>\n" +
1425
                "  <xsl:copy-of select=\"id('Z789')\"/>\n" +
1426
                "</xsl:template>\n" +
1427
                "</xsl:stylesheet>";
1428

    
1429
            XsltCompiler compiler = processor.NewXsltCompiler();
1430
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1431
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1432

    
1433
            //Create a transformer for the stylesheet
1434
            XsltTransformer transformer = exec.Load();
1435

    
1436
            // Set the root node of the source document to be the initial context node
1437
            transformer.InitialContextNode = input;
1438

    
1439
            //Set the destination
1440
            XdmDestination results = new XdmDestination();
1441

    
1442
            // Transform the XML
1443
            transformer.Run(results);
1444

    
1445
            // Show the result
1446
            Console.WriteLine(results.XdmNode.ToString());
1447

    
1448
        }
1449

    
1450
    }
1451

    
1452
    /// <summary>
1453
    /// Show a transformation using a user-written result document handler. This example
1454
    /// captures each of the result documents in a DOM, and creates a Hashtable that indexes
1455
    /// the DOM trees according to their absolute URI. On completion, it writes all the DOMs
1456
    /// to the standard output.
1457
    /// </summary>
1458

    
1459
    public class XsltUsingResultHandler : Example
1460
    {
1461

    
1462
        public override string testName
1463
        {
1464
            get { return "XsltUsingResultHandler"; }
1465
        }
1466

    
1467
        /// <summary>
1468
        /// Show a transformation using a user-written result document handler. This example
1469
        /// captures each of the result documents in a DOM, and creates a Hashtable that indexes
1470
        /// the DOM trees according to their absolute URI. On completion, it writes all the DOMs
1471
        /// to the standard output.
1472
        /// </summary>
1473

    
1474
        public override void run(Uri samplesDir)
1475
        {
1476
            // Create a Processor instance.
1477
            Processor processor = new Processor();
1478

    
1479
            // Load the source document
1480
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1481

    
1482
            // Define a stylesheet that splits the document up
1483
            String stylesheet =
1484
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1485
                "<xsl:template match='/'>\n" +
1486
                "  <xsl:for-each select='//ACT'>\n" +
1487
                "    <xsl:result-document href='{position()}.xml'>\n" +
1488
                "      <xsl:copy-of select='TITLE'/>\n" +
1489
                "    </xsl:result-document>\n" +
1490
                "  </xsl:for-each>\n" +
1491
                "</xsl:template>\n" +
1492
                "</xsl:stylesheet>";
1493

    
1494
            XsltCompiler compiler = processor.NewXsltCompiler();
1495
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1496
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1497

    
1498
            // Create a transformer for the stylesheet.
1499
            XsltTransformer transformer = exec.Load();
1500

    
1501
            // Set the root node of the source document to be the initial context node
1502
            transformer.InitialContextNode = input;
1503

    
1504
            // Establish the result document handler
1505
            Hashtable results = new Hashtable();
1506
            transformer.ResultDocumentHandler = new UserResultDocumentHandler(results);
1507

    
1508
            // Transform the source XML to a NullDestination (because we only want the secondary result files).
1509
            transformer.Run(new NullDestination());
1510

    
1511
            // Process the captured DOM results
1512
            foreach (DictionaryEntry entry in results)
1513
            {
1514
                string uri = (string)entry.Key;
1515
                Console.WriteLine("\nResult File " + uri);
1516
                DomDestination dom = (DomDestination)results[uri];
1517
                Console.Write(dom.XmlDocument.OuterXml);
1518
            }
1519

    
1520
        }
1521

    
1522
    }
1523

    
1524
    /// <summary>
1525
    /// Show a transformation using a registered collection
1526
    /// </summary>
1527

    
1528
    public class XsltUsingRegisteredCollection : Example
1529
    {
1530

    
1531
        public override string testName
1532
        {
1533
            get { return "XsltUsingRegisteredCollection"; }
1534
        }
1535

    
1536
        /// <summary>
1537
        /// Show a transformation using a registered collection
1538
        /// </summary>
1539

    
1540
        public override void run(Uri samplesDir)
1541
        {
1542
            // Create a Processor instance.
1543
            Processor processor = new Processor();
1544

    
1545
            // Load the source document
1546
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1547

    
1548
            // Define a stylesheet that splits the document up
1549
            String stylesheet =
1550
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1551
                "<xsl:template name='main'>\n" +
1552
                " <out>\n" +
1553
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1554
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1555
                "  </xsl:for-each><zzz/>\n" +
1556
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1557
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1558
                "  </xsl:for-each>\n" +
1559
                " </out>\n" +
1560
                "</xsl:template>\n" +
1561
                "</xsl:stylesheet>";
1562

    
1563
            Uri[] documentList = new Uri[2];
1564
            documentList[0] = new Uri(samplesDir, "data/othello.xml");
1565
            documentList[1] = new Uri(samplesDir, "data/books.xml");
1566
            processor.RegisterCollection(new Uri("http://www.example.org/my-collection"), documentList);
1567

    
1568
            XsltCompiler compiler = processor.NewXsltCompiler();
1569
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1570
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1571

    
1572
            // Create a transformer for the stylesheet.
1573
            XsltTransformer transformer = exec.Load();
1574

    
1575
            // Set the root node of the source document to be the initial context node
1576
            transformer.InitialTemplate = new QName("", "main");
1577

    
1578
            //Set the destination
1579
            XdmDestination results = new XdmDestination();
1580

    
1581
            // Transform the XML
1582
            transformer.Run(results);
1583

    
1584
            // Show the result
1585
            Console.WriteLine(results.XdmNode.ToString());
1586

    
1587
        }
1588
    }
1589

    
1590
    /// <summary>
1591
    /// Show a transformation using a registered collection
1592
    /// </summary>
1593

    
1594
    public class XsltUsingDirectoryCollection : Example
1595
    {
1596

    
1597
        public override string testName
1598
        {
1599
            get { return "XsltUsingDirectoryCollection"; }
1600
        }
1601

    
1602
        /// <summary>
1603
        /// Show a transformation using a collection that maps to a directory
1604
        /// </summary>
1605

    
1606
        public override void run(Uri samplesDir)
1607
        {
1608
            // Create a Processor instance.
1609
            Processor processor = new Processor();
1610

    
1611
            // Load the source document
1612
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1613

    
1614
            // Define a stylesheet that splits the document up
1615
            String stylesheet =
1616
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1617
                "<xsl:template name='main'>\n" +
1618
                " <out>\n" +
1619
                "  <xsl:for-each select=\"collection('" + samplesDir + "?recurse=yes;select=*.xml;on-error=warning')\">\n" +
1620
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1621
                "  </xsl:for-each><zzz/>\n" +
1622
                " </out>\n" +
1623
                "</xsl:template>\n" +
1624
                "</xsl:stylesheet>";
1625

    
1626

    
1627
            XsltCompiler compiler = processor.NewXsltCompiler();
1628
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1629
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1630

    
1631
            // Create a transformer for the stylesheet.
1632
            XsltTransformer transformer = exec.Load();
1633

    
1634
            // Set the root node of the source document to be the initial context node
1635
            transformer.InitialTemplate = new QName("", "main");
1636

    
1637
            //Set the destination
1638
            XdmDestination results = new XdmDestination();
1639

    
1640
            // Transform the XML
1641
            transformer.Run(results);
1642

    
1643
            // Show the result
1644
            Console.WriteLine(results.XdmNode.ToString());
1645

    
1646
        }
1647

    
1648
    }
1649

    
1650
    /// <summary>
1651
    /// Show a transformation using calls to extension functions
1652
    /// </summary>
1653

    
1654
    public class XsltExtensibility : Example
1655
    {
1656

    
1657
        public override string testName
1658
        {
1659
            get { return "XsltExtensibility"; }
1660
        }
1661

    
1662
        /// <summary>
1663
        /// Demonstrate XSLT extensibility using user-written extension functions
1664
        /// </summary>
1665
        /// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesPE, use 
1666
        /// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
1667
        /// </remarks>
1668

    
1669
        public override void run(Uri samplesDir)
1670
        {
1671

    
1672
            // Create a Processor instance.
1673
            Processor processor = new Processor();
1674

    
1675
            // Identify the Processor version
1676
            Console.WriteLine(processor.ProductVersion);
1677

    
1678
            // Set diagnostics
1679
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1680

    
1681
            // Create the stylesheet
1682
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1683
                @" xmlns:ext='clitype:SampleExtensions.SampleExtensions?asm=ExamplesPE' " +
1684
                @" xmlns:tz='clitype:System.TimeZone' " +
1685
                @" xmlns:math='http://example.math.co.uk/demo' " +
1686
                @" xmlns:env='http://example.env.co.uk/demo' " +
1687
                @" exclude-result-prefixes='ext math env tz'> " +
1688
                @" <xsl:param name='timezone' required='yes'/> " +
1689
                @" <xsl:template match='/'> " +
1690
                @" <out addition='{ext:add(2,2)}' " +
1691
                @" average='{ext:average((1,2,3,4,5,6))}' " +
1692
                @" firstchild='{ext:nameOfFirstChild(.)}' " +
1693
                @" timezone='{tz:StandardName($timezone)}' " +
1694
                @" sqrt2='{math:sqrt(2.0e0)}' " +
1695
                @" defaultNamespace='{env:defaultNamespace()}' " +
1696
                @" sqrtEmpty='{math:sqrt(())}'> " +
1697
                @" <xsl:copy-of select='ext:FirstChild((//ITEM)[1])'/> " +
1698
                @" <defaultNS value='{env:defaultNamespace()}' xsl:xpath-default-namespace='http://default.namespace.com/' /> " +
1699
                @" <combine1><xsl:sequence select='ext:combine(ext:FirstChild((//ITEM)[1]), count(*))'/></combine1> " +
1700
                @" <combine2><xsl:sequence select='ext:combine((//TITLE)[1], (//AUTHOR)[1])'/></combine2> " +
1701
                @" </out> " +
1702
                @" </xsl:template></xsl:transform>";
1703

    
1704
            // Register the integrated extension functions math:sqrt and env:defaultNamespace
1705

    
1706
            processor.RegisterExtensionFunction(new Sqrt());
1707
            processor.RegisterExtensionFunction(new DefaultNamespace());
1708

    
1709
            // Create a transformer for the stylesheet.
1710
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load();
1711

    
1712
            // Load the source document (must be a wrapper around an XmlDocument for this test)
1713
            XmlDocument doc = new XmlDocument();
1714
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/books.xml"));
1715
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
1716

    
1717
            // Set the root node of the source document to be the initial context node
1718
            transformer.InitialContextNode = input;
1719

    
1720
            // Supply a parameter
1721
            transformer.SetParameter(new QName("", "timezone"),
1722
                      XdmAtomicValue.WrapExternalObject(TimeZone.CurrentTimeZone));
1723

    
1724
            // Create a serializer
1725
            Serializer serializer = new Serializer();
1726
            serializer.SetOutputWriter(Console.Out);
1727
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1728

    
1729
            // Transform the source XML to System.out.
1730
            transformer.Run(serializer);
1731
        }
1732

    
1733
    }
1734

    
1735
    /// <summary>
1736
    /// Show a transformation using calls to extension functions
1737
    /// </summary>
1738

    
1739
    public class XsltIntegratedExtension : Example
1740
    {
1741

    
1742
        public override string testName
1743
        {
1744
            get { return "XsltIntegratedExtension"; }
1745
        }
1746

    
1747
        /// <summary>
1748
        /// Show a transformation using calls to extension functions
1749
        /// </summary>
1750

    
1751
        public override void run(Uri samplesDir)
1752
        {
1753

    
1754
            // Create a Processor instance.
1755
            Processor processor = new Processor();
1756

    
1757
            // Identify the Processor version
1758
            Console.WriteLine(processor.ProductVersion);
1759

    
1760
            // Set diagnostics
1761
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1762

    
1763
            // Create the stylesheet
1764
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1765
                @" xmlns:math='http://example.math.co.uk/demo'> " +
1766
                @" <xsl:template name='go'> " +
1767
                @" <out sqrt2='{math:sqrt(2.0e0)}' " +
1768
                @" sqrtEmpty='{math:sqrt(())}'/> " +
1769
                @" </xsl:template></xsl:transform>";
1770

    
1771
            // Register the integrated extension function math:sqrt
1772

    
1773
            processor.RegisterExtensionFunction(new Sqrt());
1774

    
1775
            // Create a transformer for the stylesheet.
1776
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load();
1777

    
1778
            // Set the root node of the source document to be the initial context node
1779
            transformer.InitialTemplate = new QName("go");
1780

    
1781
            // Create a serializer
1782
            Serializer serializer = new Serializer();
1783
            serializer.SetOutputWriter(Console.Out);
1784
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1785

    
1786
            // Transform the source XML to System.out.
1787
            transformer.Run(serializer);
1788
        }
1789

    
1790
    }
1791

    
1792
    /// <summary>
1793
    /// Example extension function to compute a square root.
1794
    /// </summary>
1795

    
1796
    public class Sqrt : ExtensionFunctionDefinition
1797
    {
1798
        public override QName FunctionName
1799
        {
1800
            get
1801
            {
1802
                return new QName("http://example.math.co.uk/demo", "sqrt");
1803
            }
1804
        }
1805

    
1806
        public override int MinimumNumberOfArguments
1807
        {
1808
            get
1809
            {
1810
                return 1;
1811
            }
1812
        }
1813

    
1814
        public override int MaximumNumberOfArguments
1815
        {
1816
            get
1817
            {
1818
                return 1;
1819
            }
1820
        }
1821

    
1822
        public override XdmSequenceType[] ArgumentTypes
1823
        {
1824
            get
1825
            {
1826
                return new XdmSequenceType[]{
1827
                    new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1828
                };
1829
            }
1830
        }
1831

    
1832
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1833
        {
1834
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?');
1835
        }
1836

    
1837
        public override bool TrustResultType
1838
        {
1839
            get
1840
            {
1841
                return true;
1842
            }
1843
        }
1844

    
1845

    
1846
        public override ExtensionFunctionCall MakeFunctionCall()
1847
        {
1848
            return new SqrtCall();
1849
        }
1850
    }
1851

    
1852
    internal class SqrtCall : ExtensionFunctionCall
1853
    {
1854
        public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
1855
        {
1856
            Boolean exists = arguments[0].MoveNext();
1857
            if (exists)
1858
            {
1859
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
1860
                double val = (double)arg.Value;
1861
                double sqrt = System.Math.Sqrt(val);
1862
                XdmAtomicValue result = new XdmAtomicValue(sqrt);
1863
                return (IXdmEnumerator)result.GetEnumerator();
1864
            }
1865
            else
1866
            {
1867
                return EmptyEnumerator.INSTANCE;
1868
            }
1869
        }
1870

    
1871
    }
1872

    
1873
    /// <summary>
1874
    /// Example extension function to return the default namespace from the static context
1875
    /// </summary>
1876

    
1877
    public class DefaultNamespace : ExtensionFunctionDefinition
1878
    {
1879
        public override QName FunctionName
1880
        {
1881
            get
1882
            {
1883
                return new QName("http://example.env.co.uk/demo", "defaultNamespace");
1884
            }
1885
        }
1886

    
1887
        public override int MinimumNumberOfArguments
1888
        {
1889
            get
1890
            {
1891
                return 0;
1892
            }
1893
        }
1894

    
1895
        public override int MaximumNumberOfArguments
1896
        {
1897
            get
1898
            {
1899
                return 0;
1900
            }
1901
        }
1902

    
1903
        public override XdmSequenceType[] ArgumentTypes
1904
        {
1905
            get
1906
            {
1907
                return new XdmSequenceType[] { };
1908
            }
1909
        }
1910

    
1911
        public override bool DependsOnFocus
1912
        {
1913
            get
1914
            {
1915
                return true;
1916
                // actually it depends on the static context rather than the focus; but returning true is necessary
1917
                // to avoid the call being extracted to a global variable.
1918
            }
1919
        }
1920

    
1921
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1922
        {
1923
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?');
1924
        }
1925

    
1926
        public override bool TrustResultType
1927
        {
1928
            get
1929
            {
1930
                return true;
1931
            }
1932
        }
1933

    
1934

    
1935
        public override ExtensionFunctionCall MakeFunctionCall()
1936
        {
1937
            return new DefaultNamespaceCall();
1938
        }
1939
    }
1940

    
1941
    internal class DefaultNamespaceCall : ExtensionFunctionCall
1942
    {
1943
        private string defaultNamespace;
1944

    
1945
        public override void SupplyStaticContext(StaticContext context)
1946
        {
1947
            defaultNamespace = context.GetNamespaceForPrefix("");
1948
        }
1949

    
1950
        public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
1951
        {
1952
            if (defaultNamespace != null)
1953
            {
1954
                return (IXdmEnumerator)new XdmAtomicValue(defaultNamespace).GetEnumerator();
1955
            }
1956
            else
1957
            {
1958
                return EmptyEnumerator.INSTANCE;
1959
            }
1960
        }
1961

    
1962
    }
1963

    
1964
    /// <summary>
1965
    /// Show a query producing a document as its result and serializing this to a FileStream
1966
    /// </summary>
1967

    
1968
    public class XQueryToStream : Example
1969
    {
1970

    
1971
        public override string testName
1972
        {
1973
            get { return "XQueryToStream"; }
1974
        }
1975

    
1976
        /// <summary>
1977
        /// Show a query producing a document as its result and serializing this to a FileStream
1978
        /// </summary>
1979

    
1980
        public override void run(Uri samplesDir)
1981
        {
1982
            Processor processor = new Processor();
1983
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1984
            compiler.BaseUri = samplesDir.ToString();
1985
            compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
1986
            XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>");
1987
            XQueryEvaluator eval = exp.Load();
1988
            Serializer qout = new Serializer();
1989
            qout.SetOutputProperty(Serializer.METHOD, "xml");
1990
            qout.SetOutputProperty(Serializer.INDENT, "yes");
1991
            qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1");
1992
            qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write));
1993
            Console.WriteLine("Output written to testoutput.xml");
1994
            eval.Run(qout);
1995
        }
1996

    
1997
    }
1998

    
1999
    /// <summary>
2000
    /// Show a query producing a single atomic value as its result and returning the value
2001
    /// to the C# application
2002
    /// </summary>
2003

    
2004
    public class XQueryToAtomicValue : Example
2005
    {
2006

    
2007
        public override string testName
2008
        {
2009
            get { return "XQueryToAtomicValue"; }
2010
        }
2011

    
2012
        /// <summary>
2013
        /// Show a query producing a single atomic value as its result and returning the value
2014
        /// to the C# application
2015
        /// </summary>
2016

    
2017
        public override void run(Uri samplesDir)
2018
        {
2019
            Processor processor = new Processor();
2020
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2021
            XQueryExecutable exp = compiler.Compile("avg(for $i in 1 to 10 return $i * $i)");
2022
            XQueryEvaluator eval = exp.Load();
2023
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2024
            Console.WriteLine("Result type: " + result.Value.GetType());
2025
            Console.WriteLine("Result value: " + (decimal)result.Value);
2026
        }
2027

    
2028
    }
2029

    
2030
    /// <summary>
2031
    /// Show a query producing a DOM as its input and producing a DOM as its output
2032
    /// </summary>
2033

    
2034
    public class XQueryToDom : Example
2035
    {
2036

    
2037
        public override string testName
2038
        {
2039
            get { return "XQueryToDom"; }
2040
        }
2041

    
2042
        /// <summary>
2043
        /// Show a query producing a DOM as its input and producing a DOM as its output
2044
        /// </summary>
2045

    
2046
        public override void run(Uri samplesDir)
2047
        {
2048
            Processor processor = new Processor();
2049

    
2050
            XmlDocument input = new XmlDocument();
2051
            input.Load(new Uri(samplesDir, "data/books.xml").ToString());
2052
            XdmNode indoc = processor.NewDocumentBuilder().Build(new XmlNodeReader(input));
2053

    
2054
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2055
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
2056
            XQueryEvaluator eval = exp.Load();
2057
            eval.ContextItem = indoc;
2058
            DomDestination qout = new DomDestination();
2059
            eval.Run(qout);
2060
            XmlDocument outdoc = qout.XmlDocument;
2061
            Console.WriteLine(outdoc.OuterXml);
2062
        }
2063

    
2064
    }
2065

    
2066
    /// <summary>
2067
    /// Show a query producing a Saxon tree as its input and producing a Saxon tree as its output
2068
    /// </summary>
2069

    
2070
    public class XQueryToXdm : Example
2071
    {
2072

    
2073
        public override string testName
2074
        {
2075
            get { return "XQueryToXdm"; }
2076
        }
2077

    
2078
        /// <summary>
2079
        /// Show a query producing a Saxon tree as its input and producing a Saxon tree as its output
2080
        /// </summary>
2081

    
2082
        public override void run(Uri samplesDir)
2083
        {
2084
            Processor processor = new Processor();
2085

    
2086
            DocumentBuilder loader = processor.NewDocumentBuilder();
2087
            loader.BaseUri = new Uri(samplesDir, "data/books.xml");
2088
            XdmNode indoc = loader.Build(loader.BaseUri);
2089

    
2090
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2091
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
2092
            XQueryEvaluator eval = exp.Load();
2093
            eval.ContextItem = indoc;
2094
            XdmDestination qout = new XdmDestination();
2095
            eval.Run(qout);
2096
            XdmNode outdoc = qout.XdmNode;
2097
            Console.WriteLine(outdoc.OuterXml);
2098
        }
2099

    
2100
    }
2101

    
2102
    /// <summary>
2103
    /// Show a query making a direct call to a user-defined function defined in the query
2104
    /// </summary>
2105

    
2106
    public class XQueryCallFunction : Example
2107
    {
2108

    
2109
        public override string testName
2110
        {
2111
            get { return "XQueryCallFunction"; }
2112
        }
2113

    
2114
        /// <summary>
2115
        /// Show a direct call on a user-defined function defined within the query
2116
        /// </summary>
2117

    
2118
        public override void run(Uri samplesDir)
2119
        {
2120
            Processor processor = new Processor();
2121

    
2122
            XQueryCompiler qc = processor.NewXQueryCompiler();
2123
            XQueryExecutable exp1 = qc.Compile("declare namespace f='f.ns';" +
2124
                   "declare variable $z := 1 + xs:integer(doc-available('" + new Uri(samplesDir, "data/books.xml").ToString() + "'));" +
2125
                   "declare variable $p as xs:integer external;" +
2126
                   "declare function f:t1($v1 as xs:integer) { " +
2127
                   "   $v1 div $z + $p" +
2128
                   "};" +
2129
                   "10");
2130
            XQueryEvaluator ev = exp1.Load();
2131
            ev.SetExternalVariable(new QName("", "p"), new XdmAtomicValue(39));
2132
            XdmValue v1 = new XdmAtomicValue(10);
2133
            XdmValue result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2134
            Console.WriteLine("First result (expected 44): " + result.ToString());
2135
            v1 = new XdmAtomicValue(20);
2136
            result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2137
            Console.WriteLine("Second result (expected 49): " + result.ToString());
2138
        }
2139

    
2140
    }
2141

    
2142

    
2143

    
2144
    /// <summary>
2145
    /// Show a query producing a sequence as its result and returning the sequence
2146
    /// to the C# application in the form of an iterator. For each item in the
2147
    /// result, its string value is output.
2148
    /// </summary>
2149

    
2150
    public class XQueryToSequence : Example
2151
    {
2152

    
2153
        public override string testName
2154
        {
2155
            get { return "XQueryToSequence"; }
2156
        }
2157

    
2158
        /// <summary>
2159
        /// Show a query producing a sequence as its result and returning the sequence
2160
        /// to the C# application in the form of an iterator. For each item in the
2161
        /// result, its string value is output.
2162
        /// </summary>
2163

    
2164
        public override void run(Uri samplesDir)
2165
        {
2166
            Processor processor = new Processor();
2167
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2168
            XQueryExecutable exp = compiler.Compile("for $i in 1 to 10 return $i * $i");
2169
            XQueryEvaluator eval = exp.Load();
2170
            XdmValue value = eval.Evaluate();
2171
            IEnumerator e = value.GetEnumerator();
2172
            while (e.MoveNext())
2173
            {
2174
                XdmItem item = (XdmItem)e.Current;
2175
                Console.WriteLine(item.ToString());
2176
            }
2177

    
2178
        }
2179

    
2180
    }
2181

    
2182
    /// <summary>
2183
    /// Show a query reading an input document using an XmlReader (the .NET XML parser)
2184
    /// </summary>
2185

    
2186
    public class XQueryFromXmlReader : Example
2187
    {
2188

    
2189
        public override string testName
2190
        {
2191
            get { return "XQueryFromXmlReader"; }
2192
        }
2193

    
2194
        /// <summary>
2195
        /// Show a query reading an input document using an XmlReader (the .NET XML parser)
2196
        /// </summary>
2197

    
2198
        public override void run(Uri samplesDir)
2199
        {
2200
            Processor processor = new Processor();
2201

    
2202
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2203
            XmlTextReader reader = new XmlTextReader(inputFileName,
2204
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2205
            //new FileStream(inputFileName, FileMode.Open, FileAccess.Read));
2206
            reader.Normalization = true;
2207

    
2208
            // add a validating reader - not to perform validation, but to expand entity references
2209
            XmlValidatingReader validator = new XmlValidatingReader(reader);
2210
            validator.ValidationType = ValidationType.None;
2211

    
2212
            XdmNode doc = processor.NewDocumentBuilder().Build(validator);
2213

    
2214
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2215
            XQueryExecutable exp = compiler.Compile("/");
2216
            XQueryEvaluator eval = exp.Load();
2217
            eval.ContextItem = doc;
2218
            Serializer qout = new Serializer();
2219
            qout.SetOutputProperty(Serializer.METHOD, "xml");
2220
            qout.SetOutputProperty(Serializer.INDENT, "yes");
2221
            qout.SetOutputStream(new FileStream("testoutput2.xml", FileMode.Create, FileAccess.Write));
2222
            eval.Run(qout);
2223
        }
2224

    
2225
    }
2226

    
2227
    /// <summary>
2228
    /// Show a query producing a sequence as its result and returning the sequence
2229
    /// to the C# application in the form of an iterator. The sequence is then
2230
    /// output by serializing each item individually, with each item on a new line.
2231
    /// </summary>
2232

    
2233
    public class XQueryToSerializedSequence : Example
2234
    {
2235

    
2236
        public override string testName
2237
        {
2238
            get { return "XQueryToSerializedSequence"; }
2239
        }
2240

    
2241
        /// <summary>
2242
        /// Show a query producing a sequence as its result and returning the sequence
2243
        /// to the C# application in the form of an iterator. The sequence is then
2244
        /// output by serializing each item individually, with each item on a new line.
2245
        /// </summary>
2246

    
2247
        public override void run(Uri samplesDir)
2248
        {
2249
            Processor processor = new Processor();
2250
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2251
            //XmlTextReader reader = new XmlTextReader(inputFileName,
2252
            //    new FileStream(inputFileName, FileMode.Open, FileAccess.Read));
2253
            XmlTextReader reader = new XmlTextReader(inputFileName,
2254
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2255
            reader.Normalization = true;
2256

    
2257
            // add a validating reader - not to perform validation, but to expand entity references
2258
            XmlValidatingReader validator = new XmlValidatingReader(reader);
2259
            validator.ValidationType = ValidationType.None;
2260

    
2261
            XdmNode doc = processor.NewDocumentBuilder().Build(reader);
2262

    
2263
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2264
            XQueryExecutable exp = compiler.Compile("//ISBN");
2265
            XQueryEvaluator eval = exp.Load();
2266
            eval.ContextItem = doc;
2267

    
2268
            foreach (XdmNode node in eval)
2269
            {
2270
                Console.WriteLine(node.OuterXml);
2271
            }
2272
        }
2273

    
2274
    }
2275

    
2276
    /// <summary>
2277
    /// Show a query that takes a parameter (external variable) as input.
2278
    /// The query produces a single atomic value as its result and returns the value
2279
    /// to the C# application. 
2280
    /// </summary>
2281

    
2282
    public class XQueryUsingParameter : Example
2283
    {
2284

    
2285
        public override string testName
2286
        {
2287
            get { return "XQueryUsingParameter"; }
2288
        }
2289

    
2290
        /// <summary>
2291
        /// Show a query that takes a parameter (external variable) as input.
2292
        /// The query produces a single atomic value as its result and returns the value
2293
        /// to the C# application. 
2294
        /// </summary>
2295

    
2296
        public override void run(Uri samplesDir)
2297
        {
2298
            Processor processor = new Processor();
2299
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2300
            compiler.DeclareNamespace("p", "http://saxon.sf.net/ns/p");
2301
            XQueryExecutable exp = compiler.Compile(
2302
                    "declare variable $p:in as xs:integer external; $p:in * $p:in");
2303
            XQueryEvaluator eval = exp.Load();
2304
            eval.SetExternalVariable(new QName("http://saxon.sf.net/ns/p", "p:in"), new XdmAtomicValue(12));
2305
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2306
            Console.WriteLine("Result type: " + result.Value.GetType());
2307
            Console.WriteLine("Result value: " + (long)result.Value);
2308
        }
2309

    
2310
    }
2311

    
2312
    /// <summary>
2313
    /// Show a query consisting of two modules, using a QueryResolver to resolve
2314
    /// the "import module" declaration
2315
    /// </summary>
2316

    
2317
    public class XQueryMultiModule : Example
2318
    {
2319

    
2320
        public override string testName
2321
        {
2322
            get { return "XQueryMultiModule"; }
2323
        }
2324

    
2325
        /// <summary>
2326
        /// Show a query consisting of two modules, using a QueryResolver to resolve
2327
        /// the "import module" declaration
2328
        /// </summary>
2329

    
2330
        public override void run(Uri samplesDir)
2331
        {
2332

    
2333
            String mod1 = "import module namespace m2 = 'http://www.example.com/module2';" +
2334
                          "m2:square(3)";
2335

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

    
2339
            Processor processor = new Processor();
2340
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2341

    
2342
            InlineModuleResolver resolver = new InlineModuleResolver();
2343
            resolver.AddModule(new Uri("http://www.example.com/module2"), mod2);
2344
            compiler.QueryResolver = resolver;
2345
            XQueryExecutable exp = compiler.Compile(mod1);
2346
            XQueryEvaluator eval = exp.Load();
2347

    
2348
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2349
            Console.WriteLine("Result type: " + result.Value.GetType());
2350
            Console.WriteLine("Result value: " + (long)result.Value);
2351
        }
2352

    
2353
        // A simple QueryResolver designed to show that the actual query
2354
        // text can come from anywhere: in this case, the resolver maintains
2355
        // a simple mapping of module URIs onto strings.
2356

    
2357
        public class InlineModuleResolver : IQueryResolver
2358
        {
2359

    
2360
            private Hashtable modules = new Hashtable();
2361

    
2362
            public void AddModule(Uri moduleName, String moduleText)
2363
            {
2364
                modules.Add(moduleName, moduleText);
2365
            }
2366

    
2367
            public Uri[] GetModules(String moduleUri, Uri baseUri, String[] locationHints)
2368
            {
2369
                Uri[] result = { new Uri(moduleUri) };
2370
                return result;
2371
            }
2372

    
2373
            public Object GetEntity(Uri absoluteUri)
2374
            {
2375
                return modules[absoluteUri];
2376
            }
2377
        }
2378

    
2379
    }
2380

    
2381
    /// <summary>
2382
    /// A try-catch expression in the query, a feature of XQuery 3.0
2383
    /// to the C# application
2384
    /// </summary>
2385

    
2386
    public class XQueryTryCatch : Example
2387
    {
2388

    
2389
        public override string testName
2390
        {
2391
            get { return "XQueryTryCatch"; }
2392
        }
2393

    
2394

    
2395
        public override void run(Uri samplesDir)
2396
        {
2397

    
2398
            String query = "xquery version '1.1'; try {doc('book.xml')}catch * {\"XQuery 1.1 catch clause - file not found.\"}";
2399
            Processor processor = new Processor();
2400

    
2401
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2402
            compiler.XQueryLanguageVersion = "1.1";
2403
            XQueryExecutable exp = compiler.Compile(query);
2404
            XQueryEvaluator eval = exp.Load();
2405
            Serializer qout = new Serializer();
2406
            eval.Run(qout);
2407
        }
2408

    
2409
    }
2410

    
2411
    /// <summary>
2412
    /// Demonstrate XQuery extensibility using user-written extension functions
2413
    /// </summary>
2414

    
2415
    public class XQueryExtensibility : Example
2416
    {
2417

    
2418
        public override string testName
2419
        {
2420
            get { return "XQueryExtensibility"; }
2421
        }
2422

    
2423
        /// <summary>
2424
        /// Demonstrate XQuery extensibility using user-written extension functions
2425
        /// </summary>
2426
        /// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesPE, use 
2427
        /// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
2428
        /// </remarks>
2429

    
2430
        public override void run(Uri samplesDir)
2431
        {
2432

    
2433
            String query =
2434
                "declare namespace ext = \"clitype:SampleExtensions.SampleExtensions?asm=ExamplesPE\";" +
2435
                "<out>" +
2436
                "  <addition>{ext:add(2,2)}</addition>" +
2437
                "  <average>{ext:average((1,2,3,4,5,6))}</average>" +
2438
                "  <language>{ext:hostLanguage()}</language>" +
2439
                "</out>";
2440

    
2441
            Processor processor = new Processor();
2442
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2443
            XQueryExecutable exp = compiler.Compile(query);
2444
            XQueryEvaluator eval = exp.Load();
2445
            Serializer qout = new Serializer();
2446
            eval.Run(qout);
2447
        }
2448

    
2449
    }
2450

    
2451

    
2452
    public class UriConnection
2453
    {
2454

    
2455
        // Get a stream for reading from a file:// URI
2456

    
2457
        public static Stream getReadableUriStream(Uri uri)
2458
        {
2459
            WebRequest request = (WebRequest)WebRequest.Create(uri);
2460
            return request.GetResponse().GetResponseStream();
2461
        }
2462

    
2463
        // Get a stream for writing to a file:// URI
2464

    
2465
        public static Stream getWritableUriStream(Uri uri)
2466
        {
2467
            FileWebRequest request = (FileWebRequest)WebRequest.CreateDefault(uri);
2468
            request.Method = "POST";
2469
            return request.GetRequestStream();
2470
        }
2471
    }
2472

    
2473

    
2474

    
2475

    
2476

    
2477

    
2478

    
2479
    ///
2480
    /// A sample XmlResolver. In the case of a URI ending with ".txt", it returns the
2481
    /// URI itself, wrapped as an XML document. In the case of the URI "empty.xslt", it returns an empty
2482
    /// stylesheet. In all other cases, it returns null, which has the effect of delegating
2483
    /// processing to the standard XmlResolver.
2484
    ///
2485

    
2486
    public class UserXmlResolver : XmlUrlResolver
2487
    {
2488

    
2489
        public String Message = null;
2490

    
2491
        public override object GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
2492
        {
2493
            if (Message != null)
2494
            {
2495
                Console.WriteLine(Message + absoluteUri + " (role=" + role + ")");
2496
            }
2497

    
2498
            if (absoluteUri.ToString().EndsWith(".txt"))
2499
            {
2500
                MemoryStream ms = new MemoryStream();
2501
                StreamWriter tw = new StreamWriter(ms);
2502
                tw.Write("<uri>");
2503
                tw.Write(absoluteUri);
2504
                tw.Write("</uri>");
2505
                tw.Flush();
2506
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2507
            }
2508
            if (absoluteUri.ToString().EndsWith("empty.xslt"))
2509
            {
2510
                String ss = "<transform xmlns='http://www.w3.org/1999/XSL/Transform' version='2.0'/>";
2511
                MemoryStream ms = new MemoryStream();
2512
                StreamWriter tw = new StreamWriter(ms);
2513
                tw.Write(ss);
2514
                tw.Flush();
2515
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2516
            }
2517
            else
2518
            {
2519
                return null;
2520
            }
2521
        }
2522
    }
2523

    
2524
    public class UserResultDocumentHandler : IResultDocumentHandler
2525
    {
2526

    
2527
        private Hashtable results;
2528

    
2529
        public UserResultDocumentHandler(Hashtable table)
2530
        {
2531
            this.results = table;
2532
        }
2533

    
2534
        public XmlDestination HandleResultDocument(string href, Uri baseUri)
2535
        {
2536
            DomDestination destination = new DomDestination();
2537
            results[href] = destination;
2538
            return destination;
2539
        }
2540

    
2541
    }
2542
}
2543

    
2544

    
2545
//
2546
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
2547
// you may not use this file except in compliance with the License. You may obtain a copy of the
2548
// License at http://www.mozilla.org/MPL/
2549
//
2550
// Software distributed under the License is distributed on an "AS IS" basis,
2551
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
2552
// See the License for the specific language governing rights and limitations under the License.
2553
//
2554
// The Original Code is: all this file.
2555
//
2556
// The Initial Developer of the Original Code is Michael H. Kay.
2557
//
2558
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
2559
//
2560
// Contributor(s): none.
2561
//
2562

    
2563

    
2564

    
2565

    
(4-4/14)