Project

Profile

Help

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

he / tags / 9.9.0.2 / samples / cs / ExamplesPE.cs @ c74fd4aa

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

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

    
76
            String samplesPath = null;
77
            Uri samplesDir;
78

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

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

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

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

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

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

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

    
208

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

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

    
225
    public class XPathSimple : Example
226
    {
227

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

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

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

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

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

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

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

    
260
	public class XPathSimple2 : Example
261
	{
262

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

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

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

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

    
279
			// Enable caching, so each expression is only compiled once
280
			xpath.Caching = true;
281

    
282
			// Compile and evaluate an XPath expression
283
			XPathSelector selector = xpath.Compile("//ITEM").Load();
284
			selector.ContextItem = input;
285
			Console.WriteLine(selector.EffectiveBooleanValue());
286

    
287
		}
288
	}
289

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

    
294
    public class XPathVariables : Example
295
    {
296

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

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

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

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

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

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

    
326
    public class XPathUndeclaredVariables : Example
327
    {
328

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

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

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

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

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

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

    
361
    public class XPathWithStaticError : Example
362
    {
363

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

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

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

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

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

    
389
    public class XPathWithDynamicError : Example
390
    {
391

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

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

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

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

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

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

    
421
    public class XsltSimple1 : Example
422
    {
423

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

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

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

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

    
440
            // Set the root node of the source document to be the initial context node
441
            transformer.InitialContextNode = input;
442

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

    
447
            // Transform the source XML and serialize the result document
448
            transformer.Run(serializer);
449
        }
450
    }
451

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

    
456
    public class XsltSimple2 : Example
457
    {
458

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

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

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

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

    
475
            // Set the root node of the source document to be the initial context node
476
            transformer.InitialContextNode = input;
477

    
478
            // Create a serializer
479
            String outfile = "OutputFromXsltSimple2.xml";
480
            Serializer serializer = new Serializer();
481
            serializer.SetOutputStream(new FileStream(outfile, FileMode.Create, FileAccess.Write));
482

    
483
			// Transform the source XML and serialize the result to the output file.
484
            transformer.Run(serializer);
485

    
486
            Console.WriteLine("\nOutput written to " + outfile + "\n");
487
        }
488
    }
489

    
490
    /// <summary>
491
    /// XSLT 2.0 transformation with source document and stylesheet supplied as files
492
    /// </summary>
493

    
494
    public class XsltSimple3 : Example
495
    {
496

    
497
        public override String testName
498
        {
499
            get { return "XsltSimple3"; }
500
        }
501

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

    
512
            // Create a Processor instance.
513
            Processor processor = new Processor();
514

    
515
            // Load the source document
516
            DocumentBuilder builder = processor.NewDocumentBuilder();
517
            builder.BaseUri = new Uri(samplesDir, "data/books.xml");
518

    
519
            XdmNode input = builder.Build(File.OpenRead(sourceFile));
520

    
521
            // Create a transformer for the stylesheet.
522
            XsltCompiler compiler = processor.NewXsltCompiler();
523
            compiler.BaseUri = new Uri(samplesDir, "styles/books.xsl");
524
            XsltTransformer transformer = compiler.Compile(File.OpenRead(styleFile)).Load();
525

    
526
            // Set the root node of the source document to be the initial context node
527
            transformer.InitialContextNode = input;
528

    
529
            // Create a serializer, with output to the standard output stream
530
            Serializer serializer = new Serializer();
531
            serializer.SetOutputWriter(Console.Out);
532

    
533
            // Transform the source XML and serialize the result document
534
            transformer.Run(serializer);
535
        }
536
    }
537

    
538

    
539
    /// <summary>
540
    /// XSLT 2.0 transformation showing stripping of whitespace controlled by the stylesheet
541
    /// </summary>
542

    
543
    public class XsltStripSpace : Example
544
    {
545

    
546
        public override String testName
547
        {
548
            get { return "XsltStripSpace"; }
549
        }
550

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

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

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

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

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

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

    
583
			// Create a serializer, with output to the standard output stream
584
            Serializer serializer = new Serializer();
585
            serializer.SetOutputWriter(Console.Out);
586

    
587
			// Transform the source XML and serialize the result document
588
            transformer.Run(serializer);
589
        }
590
    }
591

    
592

    
593
    /// <summary>
594
	/// Run a transformation, compiling the stylesheet once (into an XsltExecutable) and using it to transform two 
595
	/// different source documents
596
    /// </summary>
597

    
598
    public class XsltReuseExecutable : Example
599
    {
600

    
601
        public override String testName
602
        {
603
            get { return "XsltReuseExecutable"; }
604
        }
605

    
606
        public override void run(Uri samplesDir)
607
        {
608
            // Create a Processor instance.
609
            Processor processor = new Processor();
610

    
611
            // Create a compiled stylesheet
612
            XsltExecutable templates = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
613

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

    
617
            String sourceFile1 = "data/books.xml";
618
            String sourceFile2 = "data/othello.xml";
619

    
620
            // Do the first transformation
621
            Console.WriteLine("\n\n----- transform of " + sourceFile1 + " -----");
622
            XsltTransformer transformer1 = templates.Load();
623
            transformer1.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile1));
624
            transformer1.Run(new Serializer());     // default destination is Console.Out
625

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

    
634
    /// <summary>
635
    /// Show that the XsltTransformer is serially reusable; run a transformation twice using the same stylesheet
636
    /// and the same input document but with different parameters.
637
    /// </summary>
638

    
639
    public class XsltReuseTransformer : Example
640
    {
641

    
642
        public override String testName
643
        {
644
            get { return "XsltReuseTransformer"; }
645
        }
646

    
647
        public override void run(Uri samplesDir)
648
        {
649
            // Create a Processor instance.
650
            Processor processor = new Processor();
651

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

    
655
            // Compile the stylesheet
656
            XsltExecutable exec = processor.NewXsltCompiler().Compile(new Uri(samplesDir, "styles/summarize.xsl"));
657

    
658
            // Create a transformer 
659
            XsltTransformer transformer = exec.Load();
660

    
661
            // Run it once        
662
            transformer.SetParameter(new QName("", "", "include-attributes"), new XdmAtomicValue(false));
663
            transformer.InitialContextNode = input;
664
            XdmDestination results = new XdmDestination();
665
            transformer.Run(results);
666
            Console.WriteLine("1: " + results.XdmNode.OuterXml);
667

    
668
            // Run it again        
669
            transformer.SetParameter(new QName("", "", "include-attributes"), new XdmAtomicValue(true));
670
            transformer.InitialContextNode = input;
671
            results.Reset();
672
            transformer.Run(results);
673
            Console.WriteLine("2: " + results.XdmNode.OuterXml);
674
        }
675
    }
676

    
677
    /// <summary>
678
    /// Run a sequence of transformations in a pipeline, each one acting as a filter
679
    /// </summary>
680

    
681
    public class XsltFilterChain : Example
682
    {
683

    
684
        public override String testName
685
        {
686
            get { return "XsltFilterChain"; }
687
        }
688

    
689
        public override void run(Uri samplesDir)
690
        {
691
            // Create a Processor instance.
692
            Processor processor = new Processor();
693

    
694
            // Load the source document
695
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
696

    
697
            // Create a compiler
698
            XsltCompiler compiler = processor.NewXsltCompiler();
699

    
700
            // Compile all three stylesheets
701
            XsltTransformer transformer1 = compiler.Compile(new Uri(samplesDir, "styles/identity.xsl")).Load();
702
            XsltTransformer transformer2 = compiler.Compile(new Uri(samplesDir, "styles/books.xsl")).Load();
703
            XsltTransformer transformer3 = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
704

    
705
            // Now run them in series
706
            transformer1.InitialContextNode = input;
707
            XdmDestination results1 = new XdmDestination();
708
            transformer1.Run(results1);
709
            //Console.WriteLine("After phase 1:");
710
            //Console.WriteLine(results1.XdmNode.OuterXml);
711

    
712
            transformer2.InitialContextNode = results1.XdmNode;
713
            XdmDestination results2 = new XdmDestination();
714
            transformer2.Run(results2);
715
            //Console.WriteLine("After phase 2:");
716
            //Console.WriteLine(results2.XdmNode.OuterXml);
717

    
718
            transformer3.InitialContextNode = results2.XdmNode;
719
            XdmDestination results3 = new XdmDestination();
720
            transformer3.Run(results3);
721
            Console.WriteLine("After phase 3:");
722
            Console.WriteLine(results3.XdmNode.OuterXml);
723
        }
724
    }
725

    
726
    /// <summary>
727
    /// Transform from an XDM tree to an XDM tree
728
    /// </summary>
729

    
730
    public class XsltXdmToXdm : Example
731
    {
732

    
733
        public override String testName
734
        {
735
            get { return "XsltXdmToXdm"; }
736
        }
737

    
738
        public override void run(Uri samplesDir)
739
        {
740
            // Create a Processor instance.
741
            Processor processor = new Processor();
742

    
743
            // Load the source document
744
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
745

    
746
            // Create a compiler
747
            XsltCompiler compiler = processor.NewXsltCompiler();
748

    
749
            // Compile the stylesheet
750
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
751

    
752
            // Run the transformation
753
            transformer.InitialContextNode = input;
754
            XdmDestination result = new XdmDestination();
755
            transformer.Run(result);
756

    
757
            // Serialize the result so we can see that it worked
758
            StringWriter sw = new StringWriter();
759
            result.XdmNode.WriteTo(new XmlTextWriter(sw));
760
            Console.WriteLine(sw.ToString());
761

    
762
            // Note: we don't do 
763
            //   result.XdmNode.WriteTo(new XmlTextWriter(Console.Out));
764
            // because that results in the Console.out stream being closed, 
765
            // with subsequent attempts to write to it being rejected.
766
        }
767
    }
768

    
769
    /// <summary>
770
    /// Run an XSLT transformation from an Xdm tree, starting at a node that is not the document node
771
    /// </summary>
772

    
773
    public class XsltXdmElementToXdm : Example
774
    {
775

    
776
        public override String testName
777
        {
778
            get { return "XsltXdmElementToXdm"; }
779
        }
780

    
781
        public override void run(Uri samplesDir)
782
        {
783
            // Create a Processor instance.
784
            Processor processor = new Processor();
785

    
786
            // Load the source document
787
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
788

    
789
            // Navigate to the first grandchild
790
            XPathSelector eval = processor.NewXPathCompiler().Compile("/PLAY/FM[1]").Load();
791
            eval.ContextItem = input;
792
            input = (XdmNode)eval.EvaluateSingle();
793

    
794
            // Create an XSLT compiler
795
            XsltCompiler compiler = processor.NewXsltCompiler();
796

    
797
            // Compile the stylesheet
798
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
799

    
800
            // Run the transformation
801
            transformer.InitialContextNode = input;
802
            XdmDestination result = new XdmDestination();
803
            transformer.Run(result);
804

    
805
            // Serialize the result so we can see that it worked
806
            Console.WriteLine(result.XdmNode.OuterXml);
807
        }
808
    }
809

    
810
    /// <summary>
811
    /// Run a transformation from a DOM (System.Xml.Document) input to a DOM output
812
    /// </summary>
813

    
814
    public class XsltDomToDom : Example
815
    {
816

    
817
        public override String testName
818
        {
819
            get { return "XsltDomToDom"; }
820
        }
821

    
822
        public override void run(Uri samplesDir)
823
        {
824
            // Create a Processor instance.
825
            Processor processor = new Processor();
826

    
827
            // Load the source document (in practice, it would already exist as a DOM)
828
            XmlDocument doc = new XmlDocument();
829
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/othello.xml"));
830
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
831

    
832
            // Create a compiler
833
            XsltCompiler compiler = processor.NewXsltCompiler();
834

    
835
            // Compile the stylesheet
836
            XsltTransformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load();
837

    
838
            // Run the transformation
839
            transformer.InitialContextNode = input;
840
            DomDestination result = new DomDestination();
841
            transformer.Run(result);
842

    
843
            // Serialize the result so we can see that it worked
844
            Console.WriteLine(result.XmlDocument.OuterXml);
845
        }
846
    }
847

    
848

    
849
    /// <summary>
850
    /// Run a transformation driven by an xml-stylesheet processing instruction in the source document
851
    /// </summary>
852

    
853
    public class XsltProcessingInstruction : Example
854
    {
855

    
856
        public override string testName
857
        {
858
            get { return "XsltProcessingInstruction"; }
859
        }
860

    
861
        public override void run(Uri samplesDir)
862
        {
863
            // Create a Processor instance.
864
            Processor processor = new Processor();
865
            XsltExecutable exec;
866

    
867
            // Load the source document
868
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
869
            //Console.WriteLine("=============== source document ===============");
870
            //Console.WriteLine(input.OuterXml);
871
            //Console.WriteLine("=========== end of source document ============");
872

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

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

    
879
            XPathSelector eval = processor.NewXPathCompiler().Compile(path).Load();
880
            eval.ContextItem = input;
881
            XdmAtomicValue hrefval = (XdmAtomicValue)eval.EvaluateSingle();
882
            String href = (hrefval == null ? null : hrefval.ToString());
883

    
884
            if (href == null || href == "")
885
            {
886
                Console.WriteLine("No suitable xml-stylesheet processing instruction found");
887
                return;
888

    
889
            }
890
            else if (href[0] == '#')
891
            {
892

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

    
895
                Console.WriteLine("Locating embedded stylesheet with href = " + href);
896
                String idpath = "id('" + href.Substring(1) + "')";
897
                eval = processor.NewXPathCompiler().Compile(idpath).Load();
898
                eval.ContextItem = input;
899
                XdmNode node = (XdmNode)eval.EvaluateSingle();
900
                if (node == null)
901
                {
902
                    Console.WriteLine("No element found with ID " + href.Substring(1));
903
                    return;
904
                }
905
                exec = processor.NewXsltCompiler().Compile(node);
906

    
907
            }
908
            else
909
            {
910

    
911
                // The stylesheet is in an external document
912

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

    
915
                // Fetch and compile the referenced stylesheet
916
                exec = processor.NewXsltCompiler().Compile(new Uri(input.BaseUri, href.ToString()));
917
            }
918

    
919
            // Create a transformer 
920
            XsltTransformer transformer = exec.Load();
921

    
922
            // Run it       
923
            transformer.InitialContextNode = input;
924
            XdmDestination results = new XdmDestination();
925
            transformer.Run(results);
926
            Console.WriteLine(results.XdmNode.OuterXml);
927

    
928
        }
929
    }
930

    
931
    /// <summary>
932
    /// Run an XSLT transformation setting serialization properties from the calling application
933
    /// </summary>
934

    
935
    public class XsltSettingOutputProperties : Example
936
    {
937

    
938
        public override string testName
939
        {
940
            get { return "XsltSettingOutputProperties"; }
941
        }
942

    
943
        public override void run(Uri samplesDir)
944
        {
945
            // Create a Processor instance.
946
            Processor processor = new Processor();
947

    
948
            // Load the source document
949
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
950

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

    
954
            // Set the root node of the source document to be the initial context node
955
            transformer.InitialContextNode = input;
956

    
957
            // Create a serializer, with output to the standard output stream
958
            Serializer serializer = new Serializer();
959
            serializer.SetOutputProperty(Serializer.METHOD, "xml");
960
            serializer.SetOutputProperty(Serializer.INDENT, "no");
961
            serializer.SetOutputWriter(Console.Out);
962

    
963
            // Transform the source XML and serialize the result document
964
            transformer.Run(serializer);
965
        }
966

    
967
    }
968

    
969
    /// <summary>
970
    /// Run an XSLT transformation making use of an XmlResolver to resolve URIs at document build time, at stylesheet compile time 
971
    /// and at transformation run-time
972
    /// </summary>
973

    
974
    public class XsltUsingSourceResolver : Example
975
    {
976

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

    
982
        public override void run(Uri samplesDir)
983
        {
984

    
985
            // Create a Processor instance.
986
            Processor processor = new Processor();
987

    
988
            // Load the source document
989
            DocumentBuilder builder = processor.NewDocumentBuilder();
990
            UserXmlResolver buildTimeResolver = new UserXmlResolver();
991
            buildTimeResolver.Message = "** Calling build-time XmlResolver: ";
992
            builder.XmlResolver = buildTimeResolver;
993
            builder.BaseUri = samplesDir;
994

    
995
            String doc = "<!DOCTYPE doc [<!ENTITY e SYSTEM 'flamingo.txt'>]><doc>&e;</doc>";
996
            MemoryStream ms = new MemoryStream();
997
            StreamWriter tw = new StreamWriter(ms);
998
            tw.Write(doc);
999
            tw.Flush();
1000
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1001
            XdmNode input = builder.Build(instr);
1002

    
1003
            // Create a transformer for the stylesheet.
1004
            String stylesheet =
1005
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>" +
1006
                "<xsl:import href='empty.xslt'/>" +
1007
                "<xsl:template match='/'>" +
1008
                "<out note=\"{doc('heron.txt')}\" ><xsl:copy-of select='.'/></out>" +
1009
                "</xsl:template>" +
1010
                "</xsl:stylesheet>";
1011

    
1012
            XsltCompiler compiler = processor.NewXsltCompiler();
1013
            UserXmlResolver compileTimeResolver = new UserXmlResolver();
1014
            compileTimeResolver.Message = "** Calling compile-time XmlResolver: ";
1015
            compiler.XmlResolver = compileTimeResolver;
1016
            compiler.BaseUri = samplesDir;
1017
            XsltTransformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load();
1018

    
1019
            // Set the root node of the source document to be the initial context node
1020
            transformer.InitialContextNode = input;
1021

    
1022
            // Set the user-written XmlResolver
1023
            UserXmlResolver runTimeResolver = new UserXmlResolver();
1024
            runTimeResolver.Message = "** Calling transformation-time XmlResolver: ";
1025
            transformer.InputXmlResolver = runTimeResolver;
1026

    
1027
            // Create a serializer
1028
            Serializer serializer = new Serializer();
1029
            serializer.SetOutputWriter(Console.Out);
1030

    
1031
			// Transform the source XML and serialize the result document
1032
            transformer.Run(serializer);
1033

    
1034
        }
1035
    }
1036

    
1037
    /// <summary>
1038
    /// Run an XSLT transformation displaying compile-time errors to the console
1039
    /// </summary>
1040

    
1041
    public class XsltDisplayingErrors : Example
1042
    {
1043

    
1044
        public override string testName
1045
        {
1046
            get { return "XsltDisplayingErrors"; }
1047
        }
1048

    
1049
        public override void run(Uri samplesDir)
1050
        {
1051
            // Create a Processor instance.
1052
            Processor processor = new Processor();
1053

    
1054
            // Create the XSLT Compiler
1055
            XsltCompiler compiler = processor.NewXsltCompiler();
1056

    
1057

    
1058
            // Define a stylesheet containing errors
1059
            String stylesheet =
1060
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
1061
                "<xsl:template name='eee:template'>\n" +
1062
                "  <xsl:value-of select='32'/>\n" +
1063
                "</xsl:template>\n" +
1064
                "<xsl:template name='main'>\n" +
1065
                "  <xsl:value-of select='$var'/>\n" +
1066
                "</xsl:template>\n" +
1067
                "</xsl:stylesheet>";
1068

    
1069

    
1070
            // Attempt to compile the stylesheet and display the errors
1071
            try
1072
            {
1073
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1074
                compiler.Compile(new XmlTextReader(new StringReader(stylesheet)));
1075
                Console.WriteLine("Stylesheet compilation succeeded");
1076
            }
1077
            catch (Exception)
1078
            {
1079
                Console.WriteLine("Stylesheet compilation failed");
1080
            }
1081

    
1082

    
1083
        }
1084
    }
1085

    
1086
    /// <summary>
1087
    /// Run an XSLT transformation capturing compile-time errors within the application
1088
    /// </summary>
1089

    
1090
    public class XsltCapturingErrors : Example
1091
    {
1092

    
1093
        public override string testName
1094
        {
1095
            get { return "XsltCapturingErrors"; }
1096
        }
1097

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

    
1103
            // Create the XSLT Compiler
1104
            XsltCompiler compiler = processor.NewXsltCompiler();
1105

    
1106
            // Create a list to hold the error information
1107
            compiler.ErrorList = new ArrayList();
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='fff: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 StringReader(stylesheet));
1126
                Console.WriteLine("Stylesheet compilation succeeded");
1127
            }
1128
            catch (Exception)
1129
            {
1130
                Console.WriteLine("Stylesheet compilation failed with " + compiler.ErrorList.Count + " errors");
1131
                foreach (StaticError error in compiler.ErrorList)
1132
                {
1133
                    Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
1134
                }
1135
            }
1136
        }
1137
    }
1138

    
1139
    /// <summary>
1140
    /// Run an XSLT transformation capturing run-time messages within the application
1141
    /// </summary>
1142

    
1143
    public class XsltCapturingMessages : Example
1144
    {
1145

    
1146
        public override string testName
1147
        {
1148
            get { return "XsltCapturingMessages"; }
1149
        }
1150

    
1151
        public override void run(Uri samplesDir)
1152
        {
1153

    
1154
            // Create a Processor instance.
1155
            Processor processor = new Processor();
1156

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

    
1160
            // Define a stylesheet that generates messages
1161
            String stylesheet =
1162
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1163
                "<xsl:template name='main'>\n" +
1164
                "  <xsl:message><a>starting</a></xsl:message>\n" +
1165
                "  <out><xsl:value-of select='current-date()'/></out>\n" +
1166
                "  <xsl:message><a>finishing</a></xsl:message>\n" +
1167
                "</xsl:template>\n" +
1168
                "</xsl:stylesheet>";
1169

    
1170
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1171
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1172

    
1173

    
1174
            // Create a transformer for the stylesheet.
1175
            XsltTransformer transformer = exec.Load();
1176

    
1177
            // Set the name of the initial template
1178
            transformer.InitialTemplate = new QName("", "main");
1179

    
1180
            // Create a Listener to which messages will be written
1181
            transformer.MessageListener = new UserMessageListener();
1182

    
1183
			// Create a serializer, with output to the standard output stream
1184
            Serializer serializer = new Serializer();
1185
            serializer.SetOutputWriter(Console.Out);
1186

    
1187
			// Transform the source XML and serialize the result document
1188
            transformer.Run(serializer);
1189
        }
1190

    
1191
    }
1192

    
1193
    ///
1194
    /// Example user-written message listener
1195
    ///
1196

    
1197
    public class UserMessageListener : IMessageListener
1198
    {
1199

    
1200
        public void Message(XdmNode content, bool terminate, IXmlLocation location)
1201
        {
1202
            Console.Out.WriteLine("MESSAGE terminate=" + (terminate ? "yes" : "no") + " at " + DateTime.Now);
1203
            Console.Out.WriteLine("From instruction at line " + location.LineNumber +
1204
                    " of " + location.BaseUri);
1205
            Console.Out.WriteLine(">>" + content.StringValue);
1206
        }
1207
    }
1208

    
1209

    
1210
    /// <summary>
1211
    /// Run an XSLT transformation showing source line numbers
1212
    /// </summary>
1213

    
1214
    public class XsltShowingLineNumbers : Example
1215
    {
1216

    
1217
        public override string testName
1218
        {
1219
            get { return "XsltShowingLineNumbers"; }
1220
        }
1221

    
1222
        public override void run(Uri samplesDir)
1223
        {
1224

    
1225
            // Create a Processor instance.
1226
            Processor processor = new Processor(true);
1227

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

    
1231
            // Load the source document
1232
            DocumentBuilder builder = processor.NewDocumentBuilder();
1233
            builder.IsLineNumbering = true;
1234
            XdmNode input = builder.Build(new Uri(samplesDir, "data/othello.xml"));
1235

    
1236
            // Create the XSLT Compiler
1237
            XsltCompiler compiler = processor.NewXsltCompiler();
1238

    
1239
            // Define a stylesheet that shows line numbers of source elements
1240
            String stylesheet =
1241
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0' xmlns:saxon='http://saxon.sf.net/'>\n" +
1242
                "<xsl:template match='/'>\n" +
1243
                "<out>\n" +
1244
                "  <xsl:for-each select='//ACT'>\n" +
1245
                "  <out><xsl:value-of select='saxon:line-number(.)'/></out>\n" +
1246
                "  </xsl:for-each>\n" +
1247
                "</out>\n" +
1248
                "</xsl:template>\n" +
1249
                "</xsl:stylesheet>";
1250

    
1251
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1252
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1253

    
1254

    
1255
            // Create a transformer for the stylesheet.
1256
            XsltTransformer transformer = exec.Load();
1257

    
1258
            // Set the root node of the source document to be the initial context node
1259
            transformer.InitialContextNode = input;
1260

    
1261
			// Create a serializer, with output to the standard output stream
1262
            Serializer serializer = new Serializer();
1263
            serializer.SetOutputWriter(Console.Out);
1264

    
1265
			// Transform the source XML and serialize the result document
1266
            transformer.Run(serializer);
1267
        }
1268

    
1269
    }
1270

    
1271
    /// <summary>
1272
    /// Run an XSLT transformation producing multiple output documents
1273
    /// </summary>
1274

    
1275
    public class XsltMultipleOutput : Example
1276
    {
1277

    
1278
        public override string testName
1279
        {
1280
            get { return "XsltMultipleOutput"; }
1281
        }
1282

    
1283
        public override void run(Uri samplesDir)
1284
        {
1285
            // Create a Processor instance.
1286
            Processor processor = new Processor();
1287
            processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
1288

    
1289
            // Load the source document
1290
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1291

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

    
1295
            // Set the root node of the source document to be the initial context node
1296
            transformer.InitialContextNode = input;
1297

    
1298
            // Set the required stylesheet parameter
1299
            transformer.SetParameter(new QName("", "", "dir"), new XdmAtomicValue(samplesDir.ToString() + "play"));
1300

    
1301
			// Create a serializer, with output to the standard output stream
1302
            Serializer serializer = new Serializer();
1303
            serializer.SetOutputWriter(Console.Out);
1304

    
1305
			// Transform the source XML and serialize the result document
1306
            transformer.Run(serializer);
1307

    
1308
        }
1309

    
1310
    }
1311

    
1312

    
1313
    /// <summary>
1314
    /// Run an XSLT transformation using the id() function, with DTD validation
1315
    /// </summary>
1316

    
1317
    public class XsltUsingIdFunction : Example
1318
    {
1319

    
1320
        public override string testName
1321
        {
1322
            get { return "XsltUsingIdFunction"; }
1323
        }
1324

    
1325
        public override void run(Uri samplesDir)
1326
        {
1327
            // Create a Processor instance
1328
            Processor processor = new Processor();
1329

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

    
1334
            String doc = "<!DOCTYPE table [" +
1335
                "<!ELEMENT table (row*)>" +
1336
                "<!ELEMENT row EMPTY>" +
1337
                "<!ATTLIST row xml:id ID #REQUIRED>" +
1338
                "<!ATTLIST row value CDATA #REQUIRED>]>" +
1339
                "<table><row xml:id='A123' value='green'/><row xml:id='Z789' value='blue'/></table>";
1340

    
1341
            DocumentBuilder builder = processor.NewDocumentBuilder();
1342
            builder.DtdValidation = true;
1343
            builder.BaseUri = samplesDir;
1344
            MemoryStream ms = new MemoryStream();
1345
            StreamWriter tw = new StreamWriter(ms);
1346
            tw.Write(doc);
1347
            tw.Flush();
1348
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1349
            XdmNode input = builder.Build(instr);
1350

    
1351
            // Define a stylesheet that uses the id() function
1352
            String stylesheet =
1353
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1354
                "<xsl:template match='/'>\n" +
1355
                "  <xsl:copy-of select=\"id('Z789')\"/>\n" +
1356
                "</xsl:template>\n" +
1357
                "</xsl:stylesheet>";
1358

    
1359
            XsltCompiler compiler = processor.NewXsltCompiler();
1360
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1361
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1362

    
1363
            // Create a transformer for the stylesheet
1364
            XsltTransformer transformer = exec.Load();
1365

    
1366
            // Set the root node of the source document to be the initial context node
1367
            transformer.InitialContextNode = input;
1368

    
1369
            // Set the destination
1370
            XdmDestination results = new XdmDestination();
1371

    
1372
            // Transform the XML
1373
            transformer.Run(results);
1374

    
1375
            // Show the result
1376
            Console.WriteLine(results.XdmNode.ToString());
1377

    
1378
        }
1379

    
1380
    }
1381

    
1382
    /// <summary>
1383
    /// Show a transformation using a user-written result document handler. This example
1384
    /// captures each of the result documents in a DOM, and creates a Hashtable that indexes
1385
    /// the DOM trees according to their absolute URI. On completion, it writes all the DOMs
1386
    /// to the standard output.
1387
    /// </summary>
1388

    
1389
    public class XsltUsingResultHandler : Example
1390
    {
1391

    
1392
        public override string testName
1393
        {
1394
            get { return "XsltUsingResultHandler"; }
1395
        }
1396

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

    
1402
            // Load the source document
1403
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1404

    
1405
            // Define a stylesheet that splits the document up
1406
            String stylesheet =
1407
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1408
                "<xsl:template match='/'>\n" +
1409
                "  <xsl:for-each select='//ACT'>\n" +
1410
                "    <xsl:result-document href='{position()}.xml'>\n" +
1411
                "      <xsl:copy-of select='TITLE'/>\n" +
1412
                "    </xsl:result-document>\n" +
1413
                "  </xsl:for-each>\n" +
1414
                "</xsl:template>\n" +
1415
                "</xsl:stylesheet>";
1416

    
1417
            XsltCompiler compiler = processor.NewXsltCompiler();
1418
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1419
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1420

    
1421
            // Create a transformer for the stylesheet.
1422
            XsltTransformer transformer = exec.Load();
1423

    
1424
            // Set the root node of the source document to be the initial context node
1425
            transformer.InitialContextNode = input;
1426

    
1427
            // Establish the result document handler
1428
            Hashtable results = new Hashtable();
1429
            transformer.ResultDocumentHandler = new UserResultDocumentHandler(results);
1430

    
1431
            // Transform the source XML to a NullDestination (because we only want the secondary result files).
1432
            transformer.Run(new NullDestination());
1433

    
1434
            // Process the captured DOM results
1435
            foreach (DictionaryEntry entry in results)
1436
            {
1437
                string uri = (string)entry.Key;
1438
                Console.WriteLine("\nResult File " + uri);
1439
                DomDestination dom = (DomDestination)results[uri];
1440
                Console.Write(dom.XmlDocument.OuterXml);
1441
            }
1442

    
1443
        }
1444

    
1445
    }
1446

    
1447
    /// <summary>
1448
    /// Show a transformation using a registered collection
1449
    /// </summary>
1450

    
1451
    public class XsltUsingRegisteredCollection : Example
1452
    {
1453

    
1454
        public override string testName
1455
        {
1456
            get { return "XsltUsingRegisteredCollection"; }
1457
        }
1458

    
1459
        public override void run(Uri samplesDir)
1460
        {
1461
            // Create a Processor instance.
1462
            Processor processor = new Processor();
1463

    
1464
			// Define a stylesheet that uses the collection() function
1465
            String stylesheet =
1466
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1467
                "<xsl:template name='main'>\n" +
1468
                " <out>\n" +
1469
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1470
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1471
                "  </xsl:for-each><zzz/>\n" +
1472
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1473
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1474
                "  </xsl:for-each>\n" +
1475
                " </out>\n" +
1476
                "</xsl:template>\n" +
1477
                "</xsl:stylesheet>";
1478

    
1479
			// Register a named collection
1480
            Uri[] documentList = new Uri[2];
1481
            documentList[0] = new Uri(samplesDir, "data/othello.xml");
1482
            documentList[1] = new Uri(samplesDir, "data/books.xml");
1483
            processor.RegisterCollection(new Uri("http://www.example.org/my-collection"), documentList);
1484

    
1485
            XsltCompiler compiler = processor.NewXsltCompiler();
1486
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1487
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1488

    
1489
            // Create a transformer for the stylesheet.
1490
            XsltTransformer transformer = exec.Load();
1491

    
1492
			// Set the name of the initial template
1493
            transformer.InitialTemplate = new QName("", "main");
1494

    
1495
            // Set the destination
1496
            XdmDestination results = new XdmDestination();
1497

    
1498
            // Transform the XML
1499
            transformer.Run(results);
1500

    
1501
            // Show the result
1502
            Console.WriteLine(results.XdmNode.ToString());
1503

    
1504
        }
1505
    }
1506

    
1507
    /// <summary>
1508
	/// Show a transformation using a collection that maps to a directory
1509
    /// </summary>
1510

    
1511
    public class XsltUsingDirectoryCollection : Example
1512
    {
1513

    
1514
        public override string testName
1515
        {
1516
            get { return "XsltUsingDirectoryCollection"; }
1517
        }
1518

    
1519
        public override void run(Uri samplesDir)
1520
        {
1521
            // Create a Processor instance.
1522
            Processor processor = new Processor();
1523

    
1524
			// Define a stylesheet that uses the collection() function
1525
            String stylesheet =
1526
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1527
                "<xsl:template name='main'>\n" +
1528
                " <out>\n" +
1529
                "  <xsl:for-each select=\"collection('" + samplesDir + "?recurse=yes;select=*.xml;on-error=warning')\">\n" +
1530
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1531
                "  </xsl:for-each><zzz/>\n" +
1532
                " </out>\n" +
1533
                "</xsl:template>\n" +
1534
                "</xsl:stylesheet>";
1535

    
1536

    
1537
            XsltCompiler compiler = processor.NewXsltCompiler();
1538
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1539
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1540

    
1541
            // Create a transformer for the stylesheet.
1542
            XsltTransformer transformer = exec.Load();
1543

    
1544
			// Set the name of the initial template
1545
            transformer.InitialTemplate = new QName("", "main");
1546

    
1547
            // Set the destination
1548
            XdmDestination results = new XdmDestination();
1549

    
1550
            // Transform the XML
1551
            transformer.Run(results);
1552

    
1553
            // Show the result
1554
            Console.WriteLine(results.XdmNode.ToString());
1555

    
1556
        }
1557

    
1558
    }
1559

    
1560
	/// <summary>
1561
	/// Demonstrate XSLT extensibility using user-written extension functions
1562
	/// </summary>
1563
	/// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesPE, use 
1564
	/// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
1565
	/// </remarks>
1566

    
1567
    public class XsltExtensibility : Example
1568
    {
1569

    
1570
        public override string testName
1571
        {
1572
            get { return "XsltExtensibility"; }
1573
        }
1574

    
1575
        public override void run(Uri samplesDir)
1576
        {
1577
            // Create a Processor instance.
1578
            Processor processor = new Processor(true);
1579

    
1580
            // Identify the Processor version
1581
            Console.WriteLine(processor.ProductVersion);
1582

    
1583
            // Set diagnostics
1584
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1585

    
1586
            // Create the stylesheet
1587
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1588
                @" xmlns:ext='clitype:SampleExtensions.SampleExtensions?asm=ExamplesPE' " +
1589
                @" xmlns:tz='clitype:System.TimeZone' " +
1590
                @" xmlns:math='http://example.math.co.uk/demo' " +
1591
                @" xmlns:env='http://example.env.co.uk/demo' " +
1592
                @" exclude-result-prefixes='ext math env tz'> " +
1593
                @" <xsl:param name='timezone' required='yes'/> " +
1594
                @" <xsl:template match='/'> " +
1595
                @" <out addition='{ext:add(2,2)}' " +
1596
                @" average='{ext:average((1,2,3,4,5,6))}' " +
1597
                @" firstchild='{ext:nameOfFirstChild(.)}' " +
1598
                @" timezone='{tz:StandardName($timezone)}' " +
1599
                @" sqrt2='{math:sqrt(2.0e0)}' " +
1600
                @" defaultNamespace='{env:defaultNamespace()}' " +
1601
                @" sqrtEmpty='{math:sqrt(())}'> " +
1602
                @" <xsl:copy-of select='ext:FirstChild((//ITEM)[1])'/> " +
1603
                @" <defaultNS value='{env:defaultNamespace()}' xsl:xpath-default-namespace='http://default.namespace.com/' /> " +
1604
                @" <combine1><xsl:sequence select='ext:combine(ext:FirstChild((//ITEM)[1]), count(*))'/></combine1> " +
1605
                @" <combine2><xsl:sequence select='ext:combine((//TITLE)[1], (//AUTHOR)[1])'/></combine2> " +
1606
                @" </out> " +
1607
                @" </xsl:template></xsl:transform>";
1608

    
1609
            // Register the integrated extension functions math:sqrt and env:defaultNamespace
1610
            processor.RegisterExtensionFunction(new Sqrt());
1611
            processor.RegisterExtensionFunction(new DefaultNamespace());
1612

    
1613
            // Create a transformer for the stylesheet.
1614
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load();
1615

    
1616
            // Load the source document (must be a wrapper around an XmlDocument for this test)
1617
            XmlDocument doc = new XmlDocument();
1618
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/books.xml"));
1619
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
1620

    
1621
            // Set the root node of the source document to be the initial context node
1622
            transformer.InitialContextNode = input;
1623

    
1624
            // Supply a parameter
1625
            transformer.SetParameter(new QName("", "timezone"),
1626
                      XdmAtomicValue.WrapExternalObject(TimeZone.CurrentTimeZone));
1627

    
1628
			// Create a serializer, with output to the standard output stream
1629
            Serializer serializer = new Serializer();
1630
            serializer.SetOutputWriter(Console.Out);
1631
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1632

    
1633
			// Transform the source XML and serialize the result document
1634
            transformer.Run(serializer);
1635
        }
1636

    
1637
    }
1638

    
1639
    /// <summary>
1640
    /// Show a transformation using calls to extension functions
1641
    /// </summary>
1642

    
1643
    public class XsltIntegratedExtension : Example
1644
    {
1645

    
1646
        public override string testName
1647
        {
1648
            get { return "XsltIntegratedExtension"; }
1649
        }
1650

    
1651
        public override void run(Uri samplesDir)
1652
        {
1653

    
1654
            // Create a Processor instance.
1655
            Processor processor = new Processor();
1656

    
1657
            // Identify the Processor version
1658
            Console.WriteLine(processor.ProductVersion);
1659

    
1660
            // Set diagnostics
1661
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1662

    
1663
            // Create the stylesheet
1664
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1665
                @" xmlns:math='http://example.math.co.uk/demo'> " +
1666
                @" <xsl:template name='go'> " +
1667
                @" <out sqrt2='{math:sqrt(2.0e0)}' " +
1668
                @" sqrtEmpty='{math:sqrt(())}'/> " +
1669
                @" </xsl:template></xsl:transform>";
1670

    
1671
            // Register the integrated extension function math:sqrt
1672
            processor.RegisterExtensionFunction(new Sqrt());
1673

    
1674
            // Create a transformer for the stylesheet.
1675
            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load();
1676

    
1677
			// Set the name of the initial template
1678
            transformer.InitialTemplate = new QName("go");
1679

    
1680
			// Create a serializer, with output to the standard output stream
1681
            Serializer serializer = new Serializer();
1682
            serializer.SetOutputWriter(Console.Out);
1683
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1684

    
1685
			// Transform the source XML and serialize the result document
1686
            transformer.Run(serializer);
1687
        }
1688

    
1689
    }
1690

    
1691
    /// <summary>
1692
    /// Example extension function to compute a square root.
1693
    /// </summary>
1694

    
1695
    public class Sqrt : ExtensionFunctionDefinition
1696
    {
1697
        public override QName FunctionName
1698
        {
1699
            get
1700
            {
1701
                return new QName("http://example.math.co.uk/demo", "sqrt");
1702
            }
1703
        }
1704

    
1705
        public override int MinimumNumberOfArguments
1706
        {
1707
            get
1708
            {
1709
                return 1;
1710
            }
1711
        }
1712

    
1713
        public override int MaximumNumberOfArguments
1714
        {
1715
            get
1716
            {
1717
                return 1;
1718
            }
1719
        }
1720

    
1721
        public override XdmSequenceType[] ArgumentTypes
1722
        {
1723
            get
1724
            {
1725
                return new XdmSequenceType[]{
1726
                    new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1727
                };
1728
            }
1729
        }
1730

    
1731
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1732
        {
1733
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?');
1734
        }
1735

    
1736
        public override bool TrustResultType
1737
        {
1738
            get
1739
            {
1740
                return true;
1741
            }
1742
        }
1743

    
1744

    
1745
        public override ExtensionFunctionCall MakeFunctionCall()
1746
        {
1747
            return new SqrtCall();
1748
        }
1749
    }
1750

    
1751
    internal class SqrtCall : ExtensionFunctionCall
1752
    {
1753
        public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
1754
        {
1755
            Boolean exists = arguments[0].MoveNext();
1756
            if (exists)
1757
            {
1758
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
1759
                double val = (double)arg.Value;
1760
                double sqrt = System.Math.Sqrt(val);
1761
                XdmAtomicValue result = new XdmAtomicValue(sqrt);
1762
                return (IXdmEnumerator)result.GetEnumerator();
1763
            }
1764
            else
1765
            {
1766
                return EmptyEnumerator.INSTANCE;
1767
            }
1768
        }
1769

    
1770
    }
1771

    
1772
    /// <summary>
1773
    /// Example extension function to return the default namespace from the static context
1774
    /// </summary>
1775

    
1776
    public class DefaultNamespace : ExtensionFunctionDefinition
1777
    {
1778
        public override QName FunctionName
1779
        {
1780
            get
1781
            {
1782
                return new QName("http://example.env.co.uk/demo", "defaultNamespace");
1783
            }
1784
        }
1785

    
1786
        public override int MinimumNumberOfArguments
1787
        {
1788
            get
1789
            {
1790
                return 0;
1791
            }
1792
        }
1793

    
1794
        public override int MaximumNumberOfArguments
1795
        {
1796
            get
1797
            {
1798
                return 0;
1799
            }
1800
        }
1801

    
1802
        public override XdmSequenceType[] ArgumentTypes
1803
        {
1804
            get
1805
            {
1806
                return new XdmSequenceType[] { };
1807
            }
1808
        }
1809

    
1810
        public override bool DependsOnFocus
1811
        {
1812
            get
1813
            {
1814
                return true;
1815
                // actually it depends on the static context rather than the focus; but returning true is necessary
1816
                // to avoid the call being extracted to a global variable.
1817
            }
1818
        }
1819

    
1820
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1821
        {
1822
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?');
1823
        }
1824

    
1825
        public override bool TrustResultType
1826
        {
1827
            get
1828
            {
1829
                return true;
1830
            }
1831
        }
1832

    
1833

    
1834
        public override ExtensionFunctionCall MakeFunctionCall()
1835
        {
1836
            return new DefaultNamespaceCall();
1837
        }
1838
    }
1839

    
1840
    internal class DefaultNamespaceCall : ExtensionFunctionCall
1841
    {
1842
        private string defaultNamespace;
1843

    
1844
        public override void SupplyStaticContext(StaticContext context)
1845
        {
1846
            defaultNamespace = context.GetNamespaceForPrefix("");
1847
        }
1848

    
1849
        public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
1850
        {
1851
            if (defaultNamespace != null)
1852
            {
1853
                return (IXdmEnumerator)new XdmAtomicValue(defaultNamespace).GetEnumerator();
1854
            }
1855
            else
1856
            {
1857
                return EmptyEnumerator.INSTANCE;
1858
            }
1859
        }
1860

    
1861
    }
1862

    
1863
    /// <summary>
1864
    /// Show a query producing a document as its result and serializing this to a FileStream
1865
    /// </summary>
1866

    
1867
    public class XQueryToStream : Example
1868
    {
1869

    
1870
        public override string testName
1871
        {
1872
            get { return "XQueryToStream"; }
1873
        }
1874

    
1875
        public override void run(Uri samplesDir)
1876
        {
1877
            Processor processor = new Processor(true);
1878
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1879
            compiler.BaseUri = samplesDir.ToString();
1880
            compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
1881
            XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>");
1882
            XQueryEvaluator eval = exp.Load();
1883
            Serializer qout = new Serializer();
1884
            qout.SetOutputProperty(Serializer.METHOD, "xml");
1885
            qout.SetOutputProperty(Serializer.INDENT, "yes");
1886
            qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1");
1887
            qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write));
1888
            Console.WriteLine("Output written to testoutput.xml");
1889
            eval.Run(qout);
1890
        }
1891

    
1892
    }
1893

    
1894
    /// <summary>
1895
    /// Show a query producing a single atomic value as its result and returning the value
1896
    /// to the C# application
1897
    /// </summary>
1898

    
1899
    public class XQueryToAtomicValue : Example
1900
    {
1901

    
1902
        public override string testName
1903
        {
1904
            get { return "XQueryToAtomicValue"; }
1905
        }
1906

    
1907
        public override void run(Uri samplesDir)
1908
        {
1909
            Processor processor = new Processor();
1910
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1911
            XQueryExecutable exp = compiler.Compile("avg(for $i in 1 to 10 return $i * $i)");
1912
            XQueryEvaluator eval = exp.Load();
1913
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
1914
            Console.WriteLine("Result type: " + result.Value.GetType());
1915
            Console.WriteLine("Result value: " + (decimal)result.Value);
1916
        }
1917

    
1918
	}
1919

    
1920
	/// <summary>
1921
	/// Show a query producing a sequence as its result and returning the sequence
1922
	/// to the C# application in the form of an iterator. For each item in the
1923
	/// result, its string value is output.
1924
	/// </summary>
1925

    
1926
	public class XQueryToSequence : Example
1927
	{
1928

    
1929
		public override string testName
1930
		{
1931
			get { return "XQueryToSequence"; }
1932
		}
1933

    
1934
		public override void run(Uri samplesDir)
1935
		{
1936
			Processor processor = new Processor();
1937
			XQueryCompiler compiler = processor.NewXQueryCompiler();
1938
			XQueryExecutable exp = compiler.Compile("for $i in 1 to 10 return $i * $i");
1939
			XQueryEvaluator eval = exp.Load();
1940
			XdmValue value = eval.Evaluate();
1941
			IEnumerator e = value.GetEnumerator();
1942
			while (e.MoveNext())
1943
			{
1944
				XdmItem item = (XdmItem)e.Current;
1945
				Console.WriteLine(item.ToString());
1946
			}
1947

    
1948
		}
1949

    
1950
	}
1951

    
1952
    /// <summary>
1953
    /// Show a query producing a DOM as its input and producing a DOM as its output
1954
    /// </summary>
1955

    
1956
    public class XQueryToDom : Example
1957
    {
1958

    
1959
        public override string testName
1960
        {
1961
            get { return "XQueryToDom"; }
1962
        }
1963

    
1964
        public override void run(Uri samplesDir)
1965
        {
1966
            Processor processor = new Processor();
1967

    
1968
            XmlDocument input = new XmlDocument();
1969
            input.Load(new Uri(samplesDir, "data/books.xml").ToString());
1970
            XdmNode indoc = processor.NewDocumentBuilder().Build(new XmlNodeReader(input));
1971

    
1972
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1973
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
1974
            XQueryEvaluator eval = exp.Load();
1975
            eval.ContextItem = indoc;
1976
            DomDestination qout = new DomDestination();
1977
            eval.Run(qout);
1978
            XmlDocument outdoc = qout.XmlDocument;
1979
            Console.WriteLine(outdoc.OuterXml);
1980
        }
1981

    
1982
    }
1983

    
1984
    /// <summary>
1985
    /// Show a query producing a Saxon tree as its input and producing a Saxon tree as its output
1986
    /// </summary>
1987

    
1988
    public class XQueryToXdm : Example
1989
    {
1990

    
1991
        public override string testName
1992
        {
1993
            get { return "XQueryToXdm"; }
1994
        }
1995

    
1996
        public override void run(Uri samplesDir)
1997
        {
1998
            Processor processor = new Processor();
1999

    
2000
            DocumentBuilder loader = processor.NewDocumentBuilder();
2001
            loader.BaseUri = new Uri(samplesDir, "data/books.xml");
2002
            XdmNode indoc = loader.Build(loader.BaseUri);
2003

    
2004
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2005
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
2006
            XQueryEvaluator eval = exp.Load();
2007
            eval.ContextItem = indoc;
2008
            XdmDestination qout = new XdmDestination();
2009
            eval.Run(qout);
2010
            XdmNode outdoc = qout.XdmNode;
2011
            Console.WriteLine(outdoc.OuterXml);
2012
        }
2013

    
2014
    }
2015

    
2016
    /// <summary>
2017
    /// Show a query making a direct call to a user-defined function defined in the query
2018
    /// </summary>
2019

    
2020
    public class XQueryCallFunction : Example
2021
    {
2022

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

    
2028
        public override void run(Uri samplesDir)
2029
        {
2030
            Processor processor = new Processor();
2031

    
2032
            XQueryCompiler qc = processor.NewXQueryCompiler();
2033
            XQueryExecutable exp1 = qc.Compile("declare namespace f='f.ns';" +
2034
                   "declare variable $z := 1 + xs:integer(doc-available('" + new Uri(samplesDir, "data/books.xml").ToString() + "'));" +
2035
                   "declare variable $p as xs:integer external;" +
2036
                   "declare function f:t1($v1 as xs:integer) { " +
2037
                   "   $v1 div $z + $p" +
2038
                   "};" +
2039
                   "10");
2040
            XQueryEvaluator ev = exp1.Load();
2041
            ev.SetExternalVariable(new QName("", "p"), new XdmAtomicValue(39));
2042
            XdmValue v1 = new XdmAtomicValue(10);
2043
            XdmValue result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2044
            Console.WriteLine("First result (expected 44): " + result.ToString());
2045
            v1 = new XdmAtomicValue(20);
2046
            result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2047
            Console.WriteLine("Second result (expected 49): " + result.ToString());
2048
        }
2049

    
2050
    }
2051

    
2052
    /// <summary>
2053
    /// Show a query reading an input document using an XmlReader (the .NET XML parser)
2054
    /// </summary>
2055

    
2056
    public class XQueryFromXmlReader : Example
2057
    {
2058

    
2059
        public override string testName
2060
        {
2061
            get { return "XQueryFromXmlReader"; }
2062
        }
2063

    
2064
        public override void run(Uri samplesDir)
2065
        {
2066
            Processor processor = new Processor();
2067

    
2068
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2069
            XmlTextReader reader = new XmlTextReader(inputFileName,
2070
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2071
            //new FileStream(inputFileName, FileMode.Open, FileAccess.Read));
2072
            reader.Normalization = true;
2073

    
2074
            // add a validating reader - not to perform validation, but to expand entity references
2075
            XmlValidatingReader validator = new XmlValidatingReader(reader);
2076
            validator.ValidationType = ValidationType.None;
2077

    
2078
            XdmNode doc = processor.NewDocumentBuilder().Build(validator);
2079

    
2080
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2081
            XQueryExecutable exp = compiler.Compile("/");
2082
            XQueryEvaluator eval = exp.Load();
2083
            eval.ContextItem = doc;
2084
            Serializer qout = new Serializer();
2085
            qout.SetOutputProperty(Serializer.METHOD, "xml");
2086
            qout.SetOutputProperty(Serializer.INDENT, "yes");
2087
            qout.SetOutputStream(new FileStream("testoutput2.xml", FileMode.Create, FileAccess.Write));
2088
			Console.WriteLine("Output written to testoutput2.xml");
2089
            eval.Run(qout);
2090
        }
2091

    
2092
    }
2093

    
2094
    /// <summary>
2095
    /// Show a query producing a sequence as its result and returning the sequence
2096
    /// to the C# application in the form of an iterator. The sequence is then
2097
    /// output by serializing each item individually, with each item on a new line.
2098
    /// </summary>
2099

    
2100
    public class XQueryToSerializedSequence : Example
2101
    {
2102

    
2103
        public override string testName
2104
        {
2105
            get { return "XQueryToSerializedSequence"; }
2106
        }
2107

    
2108
        public override void run(Uri samplesDir)
2109
        {
2110
            Processor processor = new Processor();
2111
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2112
            //XmlTextReader reader = new XmlTextReader(inputFileName,
2113
            //    new FileStream(inputFileName, FileMode.Open, FileAccess.Read));
2114
            XmlTextReader reader = new XmlTextReader(inputFileName,
2115
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2116
            reader.Normalization = true;
2117

    
2118
            // add a validating reader - not to perform validation, but to expand entity references
2119
            XmlValidatingReader validator = new XmlValidatingReader(reader);
2120
            validator.ValidationType = ValidationType.None;
2121

    
2122
            XdmNode doc = processor.NewDocumentBuilder().Build(reader);
2123

    
2124
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2125
            XQueryExecutable exp = compiler.Compile("//ISBN");
2126
            XQueryEvaluator eval = exp.Load();
2127
            eval.ContextItem = doc;
2128

    
2129
            foreach (XdmNode node in eval)
2130
            {
2131
                Console.WriteLine(node.OuterXml);
2132
            }
2133
        }
2134

    
2135
    }
2136

    
2137
    /// <summary>
2138
    /// Show a query that takes a parameter (external variable) as input.
2139
    /// The query produces a single atomic value as its result and returns the value
2140
    /// to the C# application. 
2141
    /// </summary>
2142

    
2143
    public class XQueryUsingParameter : Example
2144
    {
2145

    
2146
        public override string testName
2147
        {
2148
            get { return "XQueryUsingParameter"; }
2149
        }
2150

    
2151
        public override void run(Uri samplesDir)
2152
        {
2153
            Processor processor = new Processor();
2154
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2155
            compiler.DeclareNamespace("p", "http://saxon.sf.net/ns/p");
2156
            XQueryExecutable exp = compiler.Compile(
2157
                    "declare variable $p:in as xs:integer external; $p:in * $p:in");
2158
            XQueryEvaluator eval = exp.Load();
2159
            eval.SetExternalVariable(new QName("http://saxon.sf.net/ns/p", "p:in"), new XdmAtomicValue(12));
2160
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2161
            Console.WriteLine("Result type: " + result.Value.GetType());
2162
            Console.WriteLine("Result value: " + (long)result.Value);
2163
        }
2164

    
2165
    }
2166

    
2167
    /// <summary>
2168
    /// Show a query consisting of two modules, using a QueryResolver to resolve
2169
    /// the "import module" declaration
2170
    /// </summary>
2171

    
2172
    public class XQueryMultiModule : Example
2173
    {
2174

    
2175
        public override string testName
2176
        {
2177
            get { return "XQueryMultiModule"; }
2178
        }
2179

    
2180
        public override void run(Uri samplesDir)
2181
        {
2182

    
2183
            String mod1 = "import module namespace m2 = 'http://www.example.com/module2';" +
2184
                          "m2:square(3)";
2185

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

    
2189
            Processor processor = new Processor();
2190
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2191

    
2192
            InlineModuleResolver resolver = new InlineModuleResolver();
2193
            resolver.AddModule(new Uri("http://www.example.com/module2"), mod2);
2194
            compiler.QueryResolver = resolver;
2195
            XQueryExecutable exp = compiler.Compile(mod1);
2196
            XQueryEvaluator eval = exp.Load();
2197

    
2198
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2199
            Console.WriteLine("Result type: " + result.Value.GetType());
2200
            Console.WriteLine("Result value: " + (long)result.Value);
2201
        }
2202

    
2203
        // A simple QueryResolver designed to show that the actual query
2204
        // text can come from anywhere: in this case, the resolver maintains
2205
        // a simple mapping of module URIs onto strings.
2206

    
2207
        public class InlineModuleResolver : IQueryResolver
2208
        {
2209

    
2210
            private Hashtable modules = new Hashtable();
2211

    
2212
            public void AddModule(Uri moduleName, String moduleText)
2213
            {
2214
                modules.Add(moduleName, moduleText);
2215
            }
2216

    
2217
            public Uri[] GetModules(String moduleUri, Uri baseUri, String[] locationHints)
2218
            {
2219
                Uri[] result = { new Uri(moduleUri) };
2220
                return result;
2221
            }
2222

    
2223
            public Object GetEntity(Uri absoluteUri)
2224
            {
2225
                return modules[absoluteUri];
2226
            }
2227
        }
2228

    
2229
    }
2230

    
2231
    /// <summary>
2232
	/// Demonstrate using a try-catch expression in the query, a feature of XQuery 3.0
2233
    /// </summary>
2234

    
2235
    public class XQueryTryCatch : Example
2236
    {
2237

    
2238
        public override string testName
2239
        {
2240
            get { return "XQueryTryCatch"; }
2241
        }
2242

    
2243
        public override void run(Uri samplesDir)
2244
        {
2245

    
2246
            String query = "xquery version '3.0'; try {doc('book.xml')}catch * {\"XQuery 3.0 catch clause - file not found.\"}";
2247
            Processor processor = new Processor();
2248

    
2249
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2250
            compiler.XQueryLanguageVersion = "3.0";
2251
            XQueryExecutable exp = compiler.Compile(query);
2252
            XQueryEvaluator eval = exp.Load();
2253
            Serializer qout = new Serializer();
2254
            eval.Run(qout);
2255
        }
2256

    
2257
    }
2258

    
2259
    /// <summary>
2260
    /// Demonstrate XQuery extensibility using user-written extension functions
2261
	/// </summary>
2262
	/// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesPE, use 
2263
	/// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
2264
	/// </remarks>
2265

    
2266
    public class XQueryExtensibility : Example
2267
    {
2268

    
2269
        public override string testName
2270
        {
2271
            get { return "XQueryExtensibility"; }
2272
        }
2273

    
2274
        public override void run(Uri samplesDir)
2275
        {
2276

    
2277
            String query =
2278
                "declare namespace ext = \"clitype:SampleExtensions.SampleExtensions?asm=ExamplesPE\";" +
2279
                "<out>" +
2280
                "  <addition>{ext:add(2,2)}</addition>" +
2281
                "  <average>{ext:average((1,2,3,4,5,6))}</average>" +
2282
                "  <language>{ext:hostLanguage()}</language>" +
2283
                "</out>";
2284

    
2285
            Processor processor = new Processor(true);
2286
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2287
            XQueryExecutable exp = compiler.Compile(query);
2288
            XQueryEvaluator eval = exp.Load();
2289
            Serializer qout = new Serializer();
2290
            eval.Run(qout);
2291
        }
2292

    
2293
    }
2294

    
2295

    
2296
    public class UriConnection
2297
    {
2298

    
2299
        // Get a stream for reading from a file:// URI
2300

    
2301
        public static Stream getReadableUriStream(Uri uri)
2302
        {
2303
            WebRequest request = (WebRequest)WebRequest.Create(uri);
2304
            return request.GetResponse().GetResponseStream();
2305
        }
2306

    
2307
        // Get a stream for writing to a file:// URI
2308

    
2309
        public static Stream getWritableUriStream(Uri uri)
2310
        {
2311
            FileWebRequest request = (FileWebRequest)WebRequest.CreateDefault(uri);
2312
            request.Method = "POST";
2313
            return request.GetRequestStream();
2314
        }
2315
    }
2316

    
2317

    
2318

    
2319

    
2320

    
2321

    
2322

    
2323
    ///
2324
    /// A sample XmlResolver. In the case of a URI ending with ".txt", it returns the
2325
    /// URI itself, wrapped as an XML document. In the case of the URI "empty.xslt", it returns an empty
2326
    /// stylesheet. In all other cases, it returns null, which has the effect of delegating
2327
    /// processing to the standard XmlResolver.
2328
    ///
2329

    
2330
    public class UserXmlResolver : XmlUrlResolver
2331
    {
2332

    
2333
        public String Message = null;
2334

    
2335
        public override object GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
2336
        {
2337
            if (Message != null)
2338
            {
2339
                Console.WriteLine(Message + absoluteUri + " (role=" + role + ")");
2340
            }
2341

    
2342
            if (absoluteUri.ToString().EndsWith(".txt"))
2343
            {
2344
                MemoryStream ms = new MemoryStream();
2345
                StreamWriter tw = new StreamWriter(ms);
2346
                tw.Write("<uri>");
2347
                tw.Write(absoluteUri);
2348
                tw.Write("</uri>");
2349
                tw.Flush();
2350
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2351
            }
2352
            if (absoluteUri.ToString().EndsWith("empty.xslt"))
2353
            {
2354
                String ss = "<transform xmlns='http://www.w3.org/1999/XSL/Transform' version='2.0'/>";
2355
                MemoryStream ms = new MemoryStream();
2356
                StreamWriter tw = new StreamWriter(ms);
2357
                tw.Write(ss);
2358
                tw.Flush();
2359
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2360
            }
2361
            else
2362
            {
2363
                return null;
2364
            }
2365
        }
2366
    }
2367

    
2368
    public class UserResultDocumentHandler : IResultDocumentHandler
2369
    {
2370

    
2371
        private Hashtable results;
2372

    
2373
        public UserResultDocumentHandler(Hashtable table)
2374
        {
2375
            this.results = table;
2376
        }
2377

    
2378
        public XmlDestination HandleResultDocument(string href, Uri baseUri)
2379
        {
2380
            DomDestination destination = new DomDestination();
2381
            results[href] = destination;
2382
            return destination;
2383
        }
2384

    
2385
    }
2386
}
2387

    
2388

    
2389
//
2390
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
2391
// you may not use this file except in compliance with the License. You may obtain a copy of the
2392
// License at http://www.mozilla.org/MPL/
2393
//
2394
// Software distributed under the License is distributed on an "AS IS" basis,
2395
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
2396
// See the License for the specific language governing rights and limitations under the License.
2397
//
2398
// The Original Code is: all this file.
2399
//
2400
// The Initial Developer of the Original Code is Michael H. Kay.
2401
//
2402
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
2403
//
2404
// Contributor(s): none.
2405
//
2406

    
2407

    
2408

    
2409

    
(3-3/5)