Project

Profile

Help

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

he / latest9.9 / samples / cs / ExamplesEE.cs @ 063bf4dc

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

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

    
25

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

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

    
80
            Boolean ask = true;
81
            String test = "all";
82

    
83
            String samplesPath = null;
84
            Uri samplesDir;
85

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

    
125
            }
126
            else
127
            {
128
                String home = Environment.GetEnvironmentVariable("SAXON_HOME");
129
                if (home == null)
130
                {
131
                    Console.WriteLine("No input directory supplied, and SAXON_HOME is not set");
132
                    return;
133
                }
134
                else
135
                {
136
                    if (!(home.EndsWith("/") || home.EndsWith("\\")))
137
                    {
138
                        home = home + "/";
139
                    }
140
                    samplesPath = home + "samples/";
141
                }
142
            }
143

    
144
            if (!(samplesPath.EndsWith("/") || samplesPath.EndsWith("\\")))
145
            {
146
                samplesPath = samplesPath + "/";
147
            }
148

    
149
            if (!File.Exists(samplesPath + "data/books.xml"))
150
            {
151
                Console.WriteLine("Supplied samples directory " + samplesPath + " does not contain the Saxon sample data files");
152
                return;
153
            }
154

    
155
            try
156
            {
157
                samplesDir = new Uri(samplesPath);
158
            }
159
            catch
160
            {
161
                Console.WriteLine("Invalid URI for samples directory: " + samplesPath);
162
                return;
163
            }
164

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

    
212
    ///<summary>
213
    /// Each of the example programs is implemented as a subclass of the abstract class Example
214
    ///</summary> 
215

    
216

    
217
    public abstract class Example
218
    {
219
        /// <summary>
220
        /// Read-only property: the name of the test example
221
        /// </summary>
222
        public abstract String testName { get; }
223
        /// <summary>
224
        /// Entry point for running the example
225
        /// </summary>
226
        public abstract void run(Uri samplesDir);
227
    }
228

    
229
    /// <summary>
230
    /// Evaluate an XPath expression selecting from a source document supplied as a URI
231
    /// </summary>
232

    
233
    public class XPathSimple : Example
234
    {
235

    
236
        public override String testName
237
        {
238
            get { return "XPathSimple"; }
239
        }
240

    
241
        public override void run(Uri samplesDir)
242
        {
243
            // Create a Processor instance.
244
            Processor processor = new Processor();
245

    
246
            // Load the source document
247
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
248

    
249
            // Create an XPath compiler
250
            XPathCompiler xpath = processor.NewXPathCompiler();
251

    
252
            // Enable caching, so each expression is only compiled once
253
            xpath.Caching = true;
254

    
255
            // Compile and evaluate some XPath expressions
256
            foreach (XdmItem item in xpath.Evaluate("//ITEM", input))
257
            {
258
                Console.WriteLine("TITLE: " + xpath.EvaluateSingle("string(TITLE)", item));
259
                Console.WriteLine("PRICE: " + xpath.EvaluateSingle("string(PRICE)", item));
260
            }
261
        }
262
    }
263

    
264
    /// <summary>
265
    /// Evaluate an XPath expression against a source document, returning its effective boolean value
266
    /// </summary>
267

    
268
    public class XPathSimple2 : Example
269
    {
270

    
271
        public override String testName
272
        {
273
            get { return "XPathSimple2"; }
274
        }
275

    
276
        public override void run(Uri samplesDir)
277
        {
278
            // Create a Processor instance.
279
            Processor processor = new Processor();
280

    
281
            // Load the source document
282
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
283

    
284
            // Create an XPath compiler
285
            XPathCompiler xpath = processor.NewXPathCompiler();
286

    
287
            // Enable caching, so each expression is only compiled once
288
            xpath.Caching = true;
289
            
290
            // Compile and evaluate an XPath expression
291
            XPathSelector selector = xpath.Compile("//ITEM").Load();
292
            selector.ContextItem = input;
293
            Console.WriteLine(selector.EffectiveBooleanValue());
294

    
295
        }
296
    }
297

    
298
    /// <summary>
299
    /// Evaluate an XPath expression using variables (and no source document)
300
    /// </summary>
301

    
302
    public class XPathVariables : Example
303
    {
304

    
305
        public override String testName
306
        {
307
            get { return "XPathVariables"; }
308
        }
309

    
310
        public override void run(Uri samplesDir)
311
        {
312
            // Create a Processor instance.
313
            Processor processor = new Processor();
314

    
315
            // Create the XPath expression.
316
            XPathCompiler compiler = processor.NewXPathCompiler();
317
            compiler.DeclareVariable(new QName("", "a"));
318
            compiler.DeclareVariable(new QName("", "b"));
319
            XPathSelector selector = compiler.Compile("$a + $b").Load();
320

    
321
            // Set the values of the variables
322
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(2));
323
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue(3));
324

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

    
330
    /// <summary>
331
    /// Evaluate an XPath expression using variables without explicit declaration
332
    /// </summary>
333

    
334
    public class XPathUndeclaredVariables : Example
335
    {
336

    
337
        public override String testName
338
        {
339
            get { return "XPathUndeclaredVariables"; }
340
        }
341

    
342
        public override void run(Uri samplesDir)
343
        {
344
            // Create a Processor instance.
345
            Processor processor = new Processor();
346

    
347
            // Create the XPath expression.
348
            XPathCompiler compiler = processor.NewXPathCompiler();
349
            compiler.AllowUndeclaredVariables = true;
350
            XPathExecutable expression = compiler.Compile("$a + $b");
351
            XPathSelector selector = expression.Load();
352

    
353
            // Set the values of the variables
354
            IEnumerator<QName> vars = expression.EnumerateExternalVariables2();
355
            while (vars.MoveNext())
356
            {
357
                selector.SetVariable((QName)vars.Current, new XdmAtomicValue(10));
358
            }
359

    
360
            // Evaluate the XPath expression
361
            Console.WriteLine(selector.EvaluateSingle().ToString());
362
        }
363
    }
364

    
365
    /// <summary>
366
    /// Evaluate an XPath expression throwing a static error
367
    /// </summary>
368

    
369
    public class XPathWithStaticError : Example
370
    {
371

    
372
        public override String testName
373
        {
374
            get { return "XPathWithStaticError"; }
375
        }
376

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

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

    
388
            // Evaluate the XPath expression
389
            Console.WriteLine(selector.EvaluateSingle().ToString());
390
        }
391
    }
392

    
393
    /// <summary>
394
    /// Evaluate an XPath expression throwing a dynamic error
395
    /// </summary>
396

    
397
    public class XPathWithDynamicError : Example
398
    {
399

    
400
        public override String testName
401
        {
402
            get { return "XPathWithDynamicError"; }
403
        }
404

    
405
        public override void run(Uri samplesDir)
406
        {
407
            // Create a Processor instance.
408
            Processor processor = new Processor();
409

    
410
            // Create the XPath expression.
411
            XPathCompiler compiler = processor.NewXPathCompiler();
412
            compiler.AllowUndeclaredVariables = true;
413
            XPathExecutable expression = compiler.Compile("$a gt $b");
414
            XPathSelector selector = expression.Load();
415

    
416
            // Set the values of the variables
417
            selector.SetVariable(new QName("", "a"), new XdmAtomicValue(10));
418
            selector.SetVariable(new QName("", "b"), new XdmAtomicValue("Paris"));
419

    
420
            // Evaluate the XPath expression
421
            Console.WriteLine(selector.EvaluateSingle().ToString());
422
        }
423
    }
424

    
425
    /// <summary>
426
    /// XSLT 2.0 transformation with source document and stylesheet supplied as URIs
427
    /// </summary>
428

    
429
    public class XsltSimple1 : Example
430
    {
431

    
432
        public override String testName
433
        {
434
            get { return "XsltSimple1"; }
435
        }
436

    
437
        public override void run(Uri samplesDir)
438
        {
439
            // Create a Processor instance.
440
            Processor processor = new Processor();
441

    
442
            // Load the source document
443
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
444

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

    
448
            // Set the root node of the source document to be the global context item
449
            transformer.GlobalContextItem = input;
450

    
451
            // Create a serializer, with output to the standard output stream
452
            Serializer serializer = processor.NewSerializer();
453
            serializer.SetOutputWriter(Console.Out);
454

    
455
            // Transform the source XML and serialize the result document
456
            transformer.ApplyTemplates(input, serializer);
457
        }
458
    }
459

    
460
    /// <summary>
461
    /// Run a transformation, sending the serialized output to a file
462
    /// </summary>
463

    
464
    public class XsltSimple2 : Example
465
    {
466

    
467
        public override String testName
468
        {
469
            get { return "XsltSimple2"; }
470
        }
471

    
472
        public override void run(Uri samplesDir)
473
        {
474
            // Create a Processor instance.
475
            Processor processor = new Processor();
476

    
477
            // Load the source document
478
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
479

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

    
483
            // Create a serializer
484
            String outfile = "OutputFromXsltSimple2.xml";
485
            Serializer serializer = processor.NewSerializer();
486
            serializer.SetOutputStream(new FileStream(outfile, FileMode.Create, FileAccess.Write));
487

    
488
            // Transform the source XML and serialize the result to the output file.
489
            transformer.ApplyTemplates(input, serializer);
490

    
491
            Console.WriteLine("\nOutput written to " + outfile + "\n");
492
        }
493
    }
494

    
495
    /// <summary>
496
    /// XSLT 2.0 transformation with source document and stylesheet supplied as files
497
    /// </summary>
498

    
499
    public class XsltSimple3 : Example
500
    {
501

    
502
        public override String testName
503
        {
504
            get { return "XsltSimple3"; }
505
        }
506

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

    
517
            // Create a Processor instance.
518
            Processor processor = new Processor();
519

    
520
            // Load the source document
521
            DocumentBuilder builder = processor.NewDocumentBuilder();
522
            builder.BaseUri = new Uri(samplesDir, "data/books.xml");
523

    
524
            XdmNode input = builder.Build(File.OpenRead(sourceFile));
525

    
526
            // Create a transformer for the stylesheet.
527
            XsltCompiler compiler = processor.NewXsltCompiler();
528
            compiler.BaseUri = new Uri(samplesDir, "styles/books.xsl");
529
            Xslt30Transformer transformer = compiler.Compile(File.OpenRead(styleFile)).Load30();
530

    
531
            // Set the root node of the source document to be the global context item
532
            transformer.GlobalContextItem = input;
533

    
534
            // Create a serializer, with output to the standard output stream
535
            Serializer serializer = processor.NewSerializer();
536
            serializer.SetOutputWriter(Console.Out);
537

    
538
            // Transform the source XML and serialize the result document
539
            transformer.ApplyTemplates(input, serializer);
540
        }
541
    }
542

    
543

    
544
    /// <summary>
545
    /// XSLT 2.0 transformation showing stripping of whitespace controlled by the stylesheet
546
    /// </summary>
547

    
548
    public class XsltStripSpace : Example
549
    {
550

    
551
        public override String testName
552
        {
553
            get { return "XsltStripSpace"; }
554
        }
555

    
556
        public override void run(Uri samplesDir)
557
        {
558
            Processor processor = new Processor();
559

    
560
            // Load the source document
561
            DocumentBuilder builder = processor.NewDocumentBuilder();
562
            builder.BaseUri = samplesDir;
563

    
564
            String doc = "<doc>  <a>  <b>text</b>  </a>  <a/>  </doc>";
565
            MemoryStream ms = new MemoryStream();
566
            StreamWriter tw = new StreamWriter(ms);
567
            tw.Write(doc);
568
            tw.Flush();
569
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
570
            XdmNode input = builder.Build(instr);
571

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

    
581
            XsltCompiler compiler = processor.NewXsltCompiler();
582
            compiler.BaseUri = samplesDir;
583
            Xslt30Transformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load30();
584

    
585
            // Create a serializer, with output to the standard output stream
586
            Serializer serializer = processor.NewSerializer();
587
            serializer.SetOutputWriter(Console.Out);
588

    
589
            // Transform the source XML and serialize the result document
590
            transformer.ApplyTemplates(input, serializer);
591
        }
592
    }
593

    
594

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

    
600
    public class XsltReuseExecutable : Example
601
    {
602

    
603
        public override String testName
604
        {
605
            get { return "XsltReuseExecutable"; }
606
        }
607

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

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

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

    
619
            String sourceFile1 = "data/books.xml";
620
            String sourceFile2 = "data/othello.xml";
621

    
622
            // Do the first transformation
623
            Console.WriteLine("\n\n----- transform of " + sourceFile1 + " -----");
624
            Xslt30Transformer transformer1 = templates.Load30();
625
            XdmNode input1 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile1));
626
            transformer1.ApplyTemplates(input1, processor.NewSerializer(Console.Out));     // default destination is Console.Out
627

    
628
            // Do the second transformation
629
            Console.WriteLine("\n\n----- transform of " + sourceFile2 + " -----");
630
            Xslt30Transformer transformer2 = templates.Load30();
631
            XdmNode input2 = processor.NewDocumentBuilder().Build(new Uri(samplesDir, sourceFile2));
632
            transformer2.ApplyTemplates(input2, processor.NewSerializer(Console.Out));     // default destination is Console.Out
633
        }
634
    }
635

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

    
641
    public class XsltReuseTransformer : Example
642
    {
643

    
644
        public override String testName
645
        {
646
            get { return "XsltReuseTransformer"; }
647
        }
648

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

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

    
657
            // Create a transformer 
658
            Xslt30Transformer transformer = exec.Load30();
659
            
660
            // Set the stylesheet parameters
661
            Dictionary<QName, XdmValue> params1 = new Dictionary<QName, XdmValue>();
662
            params1.Add(new QName("", "", "include-attributes"), new XdmAtomicValue(false));
663
            transformer.SetStylesheetParameters(params1);
664

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

    
668
            // Run the transformer once
669
            XdmDestination results = new XdmDestination();
670
            transformer.ApplyTemplates(input1, results);
671
            Console.WriteLine("1: " + results.XdmNode.OuterXml);
672

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

    
676
            // Run the transformer again
677
            results.Reset();
678
            transformer.ApplyTemplates(input2, results);
679
            Console.WriteLine("2: " + results.XdmNode.OuterXml);
680
        }
681
    }
682

    
683
    /// <summary>
684
    /// Run a sequence of transformations in a pipeline, each one acting as a filter
685
    /// </summary>
686

    
687
    public class XsltFilterChain : Example
688
    {
689

    
690
        public override String testName
691
        {
692
            get { return "XsltFilterChain"; }
693
        }
694

    
695
        public override void run(Uri samplesDir)
696
        {
697
            // Create a Processor instance.
698
            Processor processor = new Processor();
699

    
700
            // Load the source document
701
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
702

    
703
            // Create a compiler
704
            XsltCompiler compiler = processor.NewXsltCompiler();
705

    
706
            // Compile all three stylesheets
707
            Xslt30Transformer transformer1 = compiler.Compile(new Uri(samplesDir, "styles/identity.xsl")).Load30();
708
            Xslt30Transformer transformer2 = compiler.Compile(new Uri(samplesDir, "styles/books.xsl")).Load30();
709
            Xslt30Transformer transformer3 = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
710

    
711
            // Now run them in series
712
            XdmDestination results1 = new XdmDestination();
713
            transformer1.ApplyTemplates(input, results1);
714
            //Console.WriteLine("After phase 1:");
715
            //Console.WriteLine(results1.XdmNode.OuterXml);
716

    
717
            XdmDestination results2 = new XdmDestination();
718
            transformer2.GlobalContextItem = results1.XdmNode;
719
            transformer2.ApplyTemplates(results1.XdmNode, results2);
720
            //Console.WriteLine("After phase 2:");
721
            //Console.WriteLine(results2.XdmNode.OuterXml);
722

    
723
            XdmDestination results3 = new XdmDestination();
724
            transformer3.ApplyTemplates(results2.XdmNode, results3);
725
            Console.WriteLine("After phase 3:");
726
            Console.WriteLine(results3.XdmNode.OuterXml);
727
        }
728
    }
729

    
730
    /// <summary>
731
    /// Transform from an XDM tree to an XDM tree
732
    /// </summary>
733

    
734
    public class XsltXdmToXdm : Example
735
    {
736

    
737
        public override String testName
738
        {
739
            get { return "XsltXdmToXdm"; }
740
        }
741

    
742
        public override void run(Uri samplesDir)
743
        {
744
            // Create a Processor instance.
745
            Processor processor = new Processor();
746

    
747
            // Load the source document
748
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
749

    
750
            // Create a compiler
751
            XsltCompiler compiler = processor.NewXsltCompiler();
752

    
753
            // Compile the stylesheet
754
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
755

    
756
            // Run the transformation
757
            XdmDestination result = new XdmDestination();
758
            transformer.ApplyTemplates(input, result);
759

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

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

    
772
    /// <summary>
773
    /// Run an XSLT transformation from an XDM tree, starting at a node that is not the document node
774
    /// </summary>
775

    
776
    public class XsltXdmElementToXdm : Example
777
    {
778

    
779
        public override String testName
780
        {
781
            get { return "XsltXdmElementToXdm"; }
782
        }
783

    
784
        public override void run(Uri samplesDir)
785
        {
786
            // Create a Processor instance.
787
            Processor processor = new Processor();
788

    
789
            // Load the source document
790
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
791

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

    
797
            // Create an XSLT compiler
798
            XsltCompiler compiler = processor.NewXsltCompiler();
799

    
800
            // Compile the stylesheet
801
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
802

    
803
            // Run the transformation
804
            XdmDestination result = new XdmDestination();
805
            transformer.ApplyTemplates(input, result);
806

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

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

    
816
    public class XsltDomToDom : Example
817
    {
818

    
819
        public override String testName
820
        {
821
            get { return "XsltDomToDom"; }
822
        }
823

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

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

    
834
            // Create a compiler
835
            XsltCompiler compiler = processor.NewXsltCompiler();
836

    
837
            // Compile the stylesheet
838
            Xslt30Transformer transformer = compiler.Compile(new Uri(samplesDir, "styles/summarize.xsl")).Load30();
839

    
840
            // Run the transformation
841
            DomDestination result = new DomDestination();
842
            transformer.ApplyTemplates(input, result);
843

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

    
849

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

    
854
    public class XsltProcessingInstruction : Example
855
    {
856

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

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

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

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

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

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

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

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

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

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

    
908
            }
909
            else
910
            {
911

    
912
                // The stylesheet is in an external document
913

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

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

    
920
            // Create a transformer 
921
            Xslt30Transformer transformer = exec.Load30();
922

    
923
            // Set the root node of the source document to be the global context item
924
            transformer.GlobalContextItem = input;
925

    
926
            // Run it       
927
            XdmDestination results = new XdmDestination();
928
            transformer.ApplyTemplates(input, results);
929
            Console.WriteLine(results.XdmNode.OuterXml);
930

    
931
        }
932
    }
933

    
934
    /// <summary>
935
    /// Run an XSLT transformation setting serialization properties from the calling application
936
    /// </summary>
937

    
938
    public class XsltSettingOutputProperties : Example
939
    {
940

    
941
        public override string testName
942
        {
943
            get { return "XsltSettingOutputProperties"; }
944
        }
945

    
946
        public override void run(Uri samplesDir)
947
        {
948
            // Create a Processor instance.
949
            Processor processor = new Processor();
950

    
951
            // Load the source document
952
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/books.xml"));
953

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

    
957
            // Create a serializer, with output to the standard output stream
958
            Serializer serializer = processor.NewSerializer();
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.ApplyTemplates(input, 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
            Xslt30Transformer transformer = compiler.Compile(new XmlTextReader(new StringReader(stylesheet))).Load30();
1018

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

    
1024
            // Create a serializer
1025
            Serializer serializer = processor.NewSerializer();
1026
            serializer.SetOutputWriter(Console.Out);
1027

    
1028
            // Transform the source XML and serialize the result document
1029
            transformer.ApplyTemplates(input, serializer);
1030

    
1031
        }
1032
    }
1033

    
1034
    /// <summary>
1035
    /// Run an XSLT transformation displaying compile-time errors to the console
1036
    /// </summary>
1037

    
1038
    public class XsltDisplayingErrors : Example
1039
    {
1040

    
1041
        public override string testName
1042
        {
1043
            get { return "XsltDisplayingErrors"; }
1044
        }
1045

    
1046
        public override void run(Uri samplesDir)
1047
        {
1048
            // Create a Processor instance.
1049
            Processor processor = new Processor();
1050

    
1051
            // Create the XSLT Compiler
1052
            XsltCompiler compiler = processor.NewXsltCompiler();
1053

    
1054

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

    
1066

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

    
1079

    
1080
        }
1081
    }
1082

    
1083
    /// <summary>
1084
    /// Run an XSLT transformation capturing compile-time errors within the application
1085
    /// </summary>
1086

    
1087
    public class XsltCapturingErrors : Example
1088
    {
1089

    
1090
        public override string testName
1091
        {
1092
            get { return "XsltCapturingErrors"; }
1093
        }
1094

    
1095
        public override void run(Uri samplesDir)
1096
        {
1097
            // Create a Processor instance.
1098
            Processor processor = new Processor();
1099

    
1100
            // Create the XSLT Compiler
1101
            XsltCompiler compiler = processor.NewXsltCompiler();
1102

    
1103
            // Create a list to hold the error information
1104
            compiler.ErrorList = new List<StaticError>();
1105

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

    
1117

    
1118
            // Attempt to compile the stylesheet and display the errors
1119
            try
1120
            {
1121
                compiler.BaseUri = new Uri("http://localhost/stylesheet");
1122
                compiler.Compile(new StringReader(stylesheet));
1123
                Console.WriteLine("Stylesheet compilation succeeded");
1124
            }
1125
            catch (Exception)
1126
            {
1127
                Console.WriteLine("Stylesheet compilation failed with " + compiler.ErrorList.Count + " errors");
1128
                foreach (StaticError error in compiler.ErrorList)
1129
                {
1130
                    Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
1131
                }
1132
            }
1133
        }
1134
    }
1135

    
1136
    /// <summary>
1137
    /// Run an XSLT transformation capturing run-time messages within the application
1138
    /// </summary>
1139

    
1140
    public class XsltCapturingMessages : Example
1141
    {
1142

    
1143
        public override string testName
1144
        {
1145
            get { return "XsltCapturingMessages"; }
1146
        }
1147

    
1148
        public override void run(Uri samplesDir)
1149
        {
1150

    
1151
            // Create a Processor instance.
1152
            Processor processor = new Processor();
1153

    
1154
            // Create the XSLT Compiler
1155
            XsltCompiler compiler = processor.NewXsltCompiler();
1156

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

    
1167
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1168
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1169

    
1170

    
1171
            // Create a transformer for the stylesheet.
1172
            Xslt30Transformer transformer = exec.Load30();
1173

    
1174
            // Create a Listener to which messages will be written
1175
            transformer.MessageListener = new UserMessageListener();
1176

    
1177
            // Create a serializer, with output to the standard output stream
1178
            Serializer serializer = processor.NewSerializer();
1179
            serializer.SetOutputWriter(Console.Out);
1180

    
1181
            // Transform the source XML, calling a named initial template, and serialize the result document
1182
            transformer.CallTemplate(new QName("", "main"), serializer);
1183
        }
1184

    
1185
    }
1186

    
1187
    ///
1188
    /// Example user-written message listener
1189
    ///
1190

    
1191
    public class UserMessageListener : IMessageListener
1192
    {
1193

    
1194
        public void Message(XdmNode content, bool terminate, IXmlLocation location)
1195
        {
1196
            Console.Out.WriteLine("MESSAGE terminate=" + (terminate ? "yes" : "no") + " at " + DateTime.Now);
1197
            Console.Out.WriteLine("From instruction at line " + location.LineNumber +
1198
                    " of " + location.BaseUri);
1199
            Console.Out.WriteLine(">>" + content.StringValue);
1200
        }
1201
    }
1202

    
1203

    
1204
    /// <summary>
1205
    /// Run an XSLT transformation showing source line numbers
1206
    /// </summary>
1207

    
1208
    public class XsltShowingLineNumbers : Example
1209
    {
1210

    
1211
        public override string testName
1212
        {
1213
            get { return "XsltShowingLineNumbers"; }
1214
        }
1215

    
1216
        public override void run(Uri samplesDir)
1217
        {
1218

    
1219
            // Create a Processor instance.
1220
            Processor processor = new Processor(true);
1221

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

    
1225
            // Load the source document
1226
            DocumentBuilder builder = processor.NewDocumentBuilder();
1227
            builder.IsLineNumbering = true;
1228
            XdmNode input = builder.Build(new Uri(samplesDir, "data/othello.xml"));
1229

    
1230
            // Create the XSLT Compiler
1231
            XsltCompiler compiler = processor.NewXsltCompiler();
1232

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

    
1245
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1246
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1247

    
1248

    
1249
            // Create a transformer for the stylesheet.
1250
            Xslt30Transformer transformer = exec.Load30();
1251

    
1252
            // Create a serializer, with output to the standard output stream
1253
            Serializer serializer = processor.NewSerializer();
1254
            serializer.SetOutputWriter(Console.Out);
1255

    
1256
            // Transform the source XML and serialize the result document
1257
            transformer.ApplyTemplates(input, serializer);
1258
        }
1259

    
1260
    }
1261

    
1262
    /// <summary>
1263
    /// Run an XSLT transformation producing multiple output documents
1264
    /// </summary>
1265

    
1266
    public class XsltMultipleOutput : Example
1267
    {
1268

    
1269
        public override string testName
1270
        {
1271
            get { return "XsltMultipleOutput"; }
1272
        }
1273

    
1274
        public override void run(Uri samplesDir)
1275
        {
1276
            // Create a Processor instance.
1277
            Processor processor = new Processor();
1278
            processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
1279

    
1280
            // Load the source document
1281
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1282

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

    
1286
            // Set the required stylesheet parameter
1287
            Dictionary<QName, XdmValue> parameters = new Dictionary<QName, XdmValue>();
1288
            parameters.Add(new QName("", "", "dir"), new XdmAtomicValue(samplesDir.ToString() + "play"));
1289
            transformer.SetStylesheetParameters(parameters);
1290

    
1291
            // Create a serializer, with output to the standard output stream
1292
            Serializer serializer = processor.NewSerializer();
1293
            serializer.SetOutputWriter(Console.Out);
1294

    
1295
            // Transform the source XML and serialize the result document
1296
            transformer.ApplyTemplates(input, serializer);
1297

    
1298
        }
1299

    
1300
    }
1301

    
1302

    
1303
    /// <summary>
1304
    /// Run an XSLT transformation using the id() function, with DTD validation
1305
    /// </summary>
1306

    
1307
    public class XsltUsingIdFunction : Example
1308
    {
1309

    
1310
        public override string testName
1311
        {
1312
            get { return "XsltUsingIdFunction"; }
1313
        }
1314

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

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

    
1324
            String doc = "<!DOCTYPE table [" +
1325
                "<!ELEMENT table (row*)>" +
1326
                "<!ELEMENT row EMPTY>" +
1327
                "<!ATTLIST row xml:id ID #REQUIRED>" +
1328
                "<!ATTLIST row value CDATA #REQUIRED>]>" +
1329
                "<table><row xml:id='A123' value='green'/><row xml:id='Z789' value='blue'/></table>";
1330

    
1331
            DocumentBuilder builder = processor.NewDocumentBuilder();
1332
            builder.DtdValidation = true;
1333
            builder.BaseUri = samplesDir;
1334
            MemoryStream ms = new MemoryStream();
1335
            StreamWriter tw = new StreamWriter(ms);
1336
            tw.Write(doc);
1337
            tw.Flush();
1338
            Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
1339
            XdmNode input = builder.Build(instr);
1340

    
1341
            // Define a stylesheet that uses the id() function
1342
            String stylesheet =
1343
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1344
                "<xsl:template match='/'>\n" +
1345
                "  <xsl:copy-of select=\"id('Z789')\"/>\n" +
1346
                "</xsl:template>\n" +
1347
                "</xsl:stylesheet>";
1348

    
1349
            XsltCompiler compiler = processor.NewXsltCompiler();
1350
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1351
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1352

    
1353
            // Create a transformer for the stylesheet
1354
            Xslt30Transformer transformer = exec.Load30();
1355

    
1356
            // Set the destination
1357
            XdmDestination results = new XdmDestination();
1358

    
1359
            // Transform the XML
1360
            transformer.ApplyTemplates(input, results);
1361

    
1362
            // Show the result
1363
            Console.WriteLine(results.XdmNode.ToString());
1364

    
1365
        }
1366

    
1367
    }
1368

    
1369
    /// <summary>
1370
    /// Show a transformation using a user-written result document handler. This example
1371
    /// captures each of the result documents in a DOM, and creates a Hashtable that indexes
1372
    /// the DOM trees according to their absolute URI. On completion, it writes all the DOMs
1373
    /// to the standard output.
1374
    /// </summary>
1375

    
1376
    public class XsltUsingResultHandler : Example
1377
    {
1378

    
1379
        public override string testName
1380
        {
1381
            get { return "XsltUsingResultHandler"; }
1382
        }
1383

    
1384
        public override void run(Uri samplesDir)
1385
        {
1386
            // Create a Processor instance.
1387
            Processor processor = new Processor();
1388

    
1389
            // Load the source document
1390
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(samplesDir, "data/othello.xml"));
1391

    
1392
            // Define a stylesheet that splits the document up
1393
            String stylesheet =
1394
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1395
                "<xsl:template match='/'>\n" +
1396
                "  <xsl:for-each select='//ACT'>\n" +
1397
                "    <xsl:result-document href='{position()}.xml'>\n" +
1398
                "      <xsl:copy-of select='TITLE'/>\n" +
1399
                "    </xsl:result-document>\n" +
1400
                "  </xsl:for-each>\n" +
1401
                "</xsl:template>\n" +
1402
                "</xsl:stylesheet>";
1403

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

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

    
1411
            // Establish the result document handler
1412
            Hashtable results = new Hashtable();
1413
            transformer.ResultDocumentHandler = new UserResultDocumentHandler(results);
1414

    
1415
            // Transform the source XML to a NullDestination (because we only want the secondary result files).
1416
            NullDestination destination = new NullDestination();
1417
            destination.BaseUri = samplesDir;
1418
            transformer.ApplyTemplates(input, destination);
1419

    
1420
            // Process the captured DOM results
1421
            foreach (DictionaryEntry entry in results)
1422
            {
1423
                string uri = (string)entry.Key;
1424
                Console.WriteLine("\nResult File " + uri);
1425
                DomDestination dom = (DomDestination)results[uri];
1426
                Console.Write(dom.XmlDocument.OuterXml);
1427
            }
1428

    
1429
        }
1430

    
1431
    }
1432

    
1433
    /// <summary>
1434
    /// Show a transformation using a registered collection
1435
    /// </summary>
1436

    
1437
    public class XsltUsingRegisteredCollection : Example
1438
    {
1439

    
1440
        public override string testName
1441
        {
1442
            get { return "XsltUsingRegisteredCollection"; }
1443
        }
1444

    
1445
        public override void run(Uri samplesDir)
1446
        {
1447
            // Create a Processor instance.
1448
            Processor processor = new Processor();
1449

    
1450
            // Define a stylesheet that uses the collection() function
1451
            String stylesheet =
1452
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1453
                "<xsl:template name='main'>\n" +
1454
                " <out>\n" +
1455
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1456
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1457
                "  </xsl:for-each><zzz/>\n" +
1458
                "  <xsl:for-each select=\"collection('http://www.example.org/my-collection')\">\n" +
1459
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1460
                "  </xsl:for-each>\n" +
1461
                " </out>\n" +
1462
                "</xsl:template>\n" +
1463
                "</xsl:stylesheet>";
1464

    
1465
            // Register a named collection
1466
            Uri[] documentList = new Uri[2];
1467
            documentList[0] = new Uri(samplesDir, "data/othello.xml");
1468
            documentList[1] = new Uri(samplesDir, "data/books.xml");
1469
            processor.RegisterCollection(new Uri("http://www.example.org/my-collection"), documentList);
1470

    
1471
            XsltCompiler compiler = processor.NewXsltCompiler();
1472
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1473
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1474

    
1475
            // Create a transformer for the stylesheet.
1476
            Xslt30Transformer transformer = exec.Load30();
1477

    
1478
            // Set the destination
1479
            XdmDestination results = new XdmDestination();
1480

    
1481
            // Transform the XML, calling a named initial template
1482
            transformer.CallTemplate(new QName("", "main"), results);
1483

    
1484
            // Show the result
1485
            Console.WriteLine(results.XdmNode.ToString());
1486

    
1487
        }
1488
    }
1489

    
1490
    /// <summary>
1491
    /// Show a transformation using a collection that maps to a directory
1492
    /// </summary>
1493

    
1494
    public class XsltUsingDirectoryCollection : Example
1495
    {
1496

    
1497
        public override string testName
1498
        {
1499
            get { return "XsltUsingDirectoryCollection"; }
1500
        }
1501

    
1502
        public override void run(Uri samplesDir)
1503
        {
1504
            // Create a Processor instance.
1505
            Processor processor = new Processor();
1506

    
1507
            // Define a stylesheet that uses the collection() function
1508
            String stylesheet =
1509
                "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>\n" +
1510
                "<xsl:template name='main'>\n" +
1511
                " <out>\n" +
1512
                "  <xsl:for-each select=\"collection('" + samplesDir + "?recurse=yes;select=*.xml;on-error=warning')\">\n" +
1513
                "    <document uri='{document-uri(.)}' nodes='{count(//*)}'/>\n" +
1514
                "  </xsl:for-each><zzz/>\n" +
1515
                " </out>\n" +
1516
                "</xsl:template>\n" +
1517
                "</xsl:stylesheet>";
1518

    
1519

    
1520
            XsltCompiler compiler = processor.NewXsltCompiler();
1521
            compiler.BaseUri = new Uri("http://localhost/stylesheet");
1522
            XsltExecutable exec = compiler.Compile(new StringReader(stylesheet));
1523

    
1524
            // Create a transformer for the stylesheet.
1525
            Xslt30Transformer transformer = exec.Load30();
1526

    
1527
            // Set the destination
1528
            XdmDestination results = new XdmDestination();
1529

    
1530
            // Transform the XML, calling a named initial template
1531
            transformer.CallTemplate(new QName("", "main"), results);
1532

    
1533
            // Show the result
1534
            Console.WriteLine(results.XdmNode.ToString());
1535

    
1536
        }
1537

    
1538
    }
1539

    
1540
    /// <summary>
1541
    /// Demonstrate XSLT extensibility using user-written reflexive extension functions
1542
    /// </summary>
1543
    /// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesEE, use 
1544
    /// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
1545
    /// Alternatively, the location of an assembly can be provided as a URI using the 'from' keyword
1546
    /// e.g. clitype:SampleExtensions.SampleExtensions?from=file:///c:/lib/SampleExtensions.dll
1547
    /// </remarks>
1548

    
1549
    public class XsltExtensibility : Example
1550
    {
1551

    
1552
        public override string testName
1553
        {
1554
            get { return "XsltExtensibility"; }
1555
        }
1556

    
1557
        public override void run(Uri samplesDir)
1558
        {
1559
            // Create a Processor instance.
1560
            Processor processor = new Processor(true);
1561

    
1562
            // Identify the Processor version
1563
            Console.WriteLine(processor.ProductVersion);
1564

    
1565
            // Set diagnostics
1566
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1567

    
1568
            // Create the stylesheet
1569
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1570
                @" xmlns:ext='clitype:SampleExtensions.SampleExtensions?asm=ExamplesEE' " +
1571
                @" xmlns:tz='clitype:System.TimeZone' " +
1572
                @" exclude-result-prefixes='ext tz'> " +
1573
                @" <xsl:param name='timezone' required='yes'/> " +
1574
                @" <xsl:template match='/'> " +
1575
                @" <out addition='{ext:add(2,2)}' " +
1576
                @" average='{ext:average((1,2,3,4,5,6))}' " +
1577
                @" firstchild='{ext:nameOfFirstChild(.)}' " +
1578
                @" timezone='{tz:StandardName($timezone)}' >" +
1579
                @" <xsl:copy-of select='ext:FirstChild((//ITEM)[1])'/> " +
1580
                @" <combine1><xsl:sequence select='ext:combine(ext:FirstChild((//ITEM)[1]), count(*))'/></combine1> " +
1581
                @" <combine2><xsl:sequence select='ext:combine((//TITLE)[1], (//AUTHOR)[1])'/></combine2> " +
1582
                @" </out> " +
1583
                @" </xsl:template></xsl:transform>";
1584

    
1585
            // Create a transformer for the stylesheet.
1586
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
1587

    
1588
            // Load the source document (must be a wrapper around an XmlDocument for this test)
1589
            XmlDocument doc = new XmlDocument();
1590
            doc.Load(new XmlTextReader(samplesDir.AbsolutePath + "data/books.xml"));
1591
            XdmNode input = processor.NewDocumentBuilder().Wrap(doc);
1592

    
1593
            // Supply a parameter
1594
            Dictionary<QName, XdmValue> parameters = new Dictionary<QName, XdmValue>();
1595
            parameters.Add(new QName("", "timezone"), new XdmExternalObjectValue(TimeZone.CurrentTimeZone));
1596
            transformer.SetStylesheetParameters(parameters);
1597

    
1598
            // Create a serializer, with output to the standard output stream
1599
            Serializer serializer = processor.NewSerializer();
1600
            serializer.SetOutputWriter(Console.Out);
1601
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1602

    
1603
            // Transform the source XML and serialize the result document
1604
            transformer.ApplyTemplates(input, serializer);
1605
        }
1606

    
1607
    }
1608

    
1609
    /// <summary>
1610
    /// Show a transformation using calls to integrated extension functions (full API)
1611
    /// </summary>
1612

    
1613
    public class XsltIntegratedExtension : Example
1614
    {
1615

    
1616
        public override string testName
1617
        {
1618
            get { return "XsltIntegratedExtension"; }
1619
        }
1620

    
1621
        public override void run(Uri samplesDir)
1622
        {
1623

    
1624
            // Create a Processor instance.
1625
            Processor processor = new Processor();
1626

    
1627
            // Identify the Processor version
1628
            Console.WriteLine(processor.ProductVersion);
1629

    
1630
            // Set diagnostics
1631
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1632

    
1633
            // Create the stylesheet
1634
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1635
                @" xmlns:math='http://example.math.co.uk/demo' " +
1636
                @" xmlns:env='http://example.env.co.uk/demo' " +
1637
                @" exclude-result-prefixes='math env'> " +
1638
                @" <xsl:template name='go'> " +
1639
                @" <out sqrt2='{math:sqrt(2.0e0)}' " +
1640
                @" defaultNamespace='{env:defaultNamespace()}' " +
1641
                @" sqrtEmpty='{math:sqrt(())}'> " +
1642
                @" <defaultNS value='{env:defaultNamespace()}' xsl:xpath-default-namespace='http://default.namespace.com/' /> " +
1643
                @" </out> " +
1644
                @" </xsl:template></xsl:transform>";
1645

    
1646
            // Register the integrated extension functions math:sqrt and env:defaultNamespace
1647
            processor.RegisterExtensionFunction(new Sqrt());
1648
            processor.RegisterExtensionFunction(new DefaultNamespace());
1649

    
1650
            // Create a transformer for the stylesheet.
1651
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
1652

    
1653
            // Create a serializer, with output to the standard output stream
1654
            Serializer serializer = processor.NewSerializer();
1655
            serializer.SetOutputWriter(Console.Out);
1656
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1657

    
1658
            // Transform the source XML, calling a named initial template, and serialize the result document
1659
            transformer.CallTemplate(new QName("go"), serializer);
1660
        }
1661

    
1662
    }
1663

    
1664
    /// <summary>
1665
    /// Example extension function to compute a square root, using the full API
1666
    /// </summary>
1667

    
1668
    public class Sqrt : ExtensionFunctionDefinition
1669
    {
1670
        public override QName FunctionName
1671
        {
1672
            get
1673
            {
1674
                return new QName("http://example.math.co.uk/demo", "sqrt");
1675
            }
1676
        }
1677

    
1678
        public override int MinimumNumberOfArguments
1679
        {
1680
            get
1681
            {
1682
                return 1;
1683
            }
1684
        }
1685

    
1686
        public override int MaximumNumberOfArguments
1687
        {
1688
            get
1689
            {
1690
                return 1;
1691
            }
1692
        }
1693

    
1694
        public override XdmSequenceType[] ArgumentTypes
1695
        {
1696
            get
1697
            {
1698
                return new XdmSequenceType[]{
1699
                    new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1700
                };
1701
            }
1702
        }
1703

    
1704
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1705
        {
1706
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?');
1707
        }
1708

    
1709
        public override bool TrustResultType
1710
        {
1711
            get
1712
            {
1713
                return true;
1714
            }
1715
        }
1716

    
1717

    
1718
        public override ExtensionFunctionCall MakeFunctionCall()
1719
        {
1720
            return new SqrtCall();
1721
        }
1722
    }
1723

    
1724
    internal class SqrtCall : ExtensionFunctionCall
1725
    {
1726
        public override IEnumerator<XdmItem> Call(IEnumerator<XdmItem>[] arguments, DynamicContext context)
1727
        {
1728
            Boolean exists = arguments[0].MoveNext();
1729
            if (exists)
1730
            {
1731
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
1732
                double val = (double)arg.Value;
1733
                double sqrt = System.Math.Sqrt(val);
1734
                return new XdmAtomicValue(sqrt).GetEnumerator();
1735
            }
1736
            else
1737
            {
1738
                return EmptyEnumerator<XdmItem>.INSTANCE;
1739
            }
1740
        }
1741
    }
1742

    
1743
    /// <summary>
1744
    /// Example extension function to return the default namespace from the static context
1745
    /// </summary>
1746

    
1747
    public class DefaultNamespace : ExtensionFunctionDefinition
1748
    {
1749
        public override QName FunctionName
1750
        {
1751
            get
1752
            {
1753
                return new QName("http://example.env.co.uk/demo", "defaultNamespace");
1754
            }
1755
        }
1756

    
1757
        public override int MinimumNumberOfArguments
1758
        {
1759
            get
1760
            {
1761
                return 0;
1762
            }
1763
        }
1764

    
1765
        public override int MaximumNumberOfArguments
1766
        {
1767
            get
1768
            {
1769
                return 0;
1770
            }
1771
        }
1772

    
1773
        public override XdmSequenceType[] ArgumentTypes
1774
        {
1775
            get
1776
            {
1777
                return new XdmSequenceType[] { };
1778
            }
1779
        }
1780

    
1781
        public override bool DependsOnFocus
1782
        {
1783
            get
1784
            {
1785
                return true;
1786
                // actually it depends on the static context rather than the focus; but returning true is necessary
1787
                // to avoid the call being extracted to a global variable.
1788
            }
1789
        }
1790

    
1791
        public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
1792
        {
1793
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?');
1794
        }
1795

    
1796
        public override bool TrustResultType
1797
        {
1798
            get
1799
            {
1800
                return true;
1801
            }
1802
        }
1803

    
1804
        public override ExtensionFunctionCall MakeFunctionCall()
1805
        {
1806
            return new DefaultNamespaceCall();
1807
        }
1808
    }
1809

    
1810
    internal class DefaultNamespaceCall : ExtensionFunctionCall
1811
    {
1812
        private string defaultNamespace;
1813

    
1814
        public override void SupplyStaticContext(StaticContext context)
1815
        {
1816
            defaultNamespace = context.GetNamespaceForPrefix("");
1817
        }
1818

    
1819
        public override IEnumerator<XdmItem> Call(IEnumerator<XdmItem>[] arguments, DynamicContext context)
1820
        {
1821
            if (defaultNamespace != null)
1822
            {
1823
                return new XdmAtomicValue(defaultNamespace).GetEnumerator();
1824
            }
1825
            else
1826
            {
1827
                return EmptyEnumerator<XdmItem>.INSTANCE;
1828
            }
1829
        }
1830
    }
1831

    
1832
    /// <summary>
1833
    /// Show a transformation using calls to an integrated extension function (simple API)
1834
    /// </summary>
1835

    
1836
    public class XsltSimpleExtension : Example
1837
    {
1838

    
1839
        public override string testName
1840
        {
1841
            get { return "XsltSimpleExtension"; }
1842
        }
1843

    
1844
        public override void run(Uri samplesDir)
1845
        {
1846

    
1847
            // Create a Processor instance.
1848
            Processor processor = new Processor();
1849

    
1850
            // Identify the Processor version
1851
            Console.WriteLine(processor.ProductVersion);
1852

    
1853
            // Set diagnostics
1854
            //processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true");
1855

    
1856
            // Create the stylesheet
1857
            String s = @"<xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
1858
                @" xmlns:math='http://example.math.co.uk/demo'> " +
1859
                @" <xsl:template name='go'> " +
1860
                @" <out sqrt2='{math:sqrtSimple(2.0e0)}' " +
1861
                @" sqrtEmpty='{math:sqrtSimple(())}'/> " +
1862
                @" </xsl:template></xsl:transform>";
1863

    
1864
            // Register the integrated extension function math:sqrtSimple
1865
            processor.RegisterExtensionFunction(new SqrtSimple());
1866

    
1867
            // Create a transformer for the stylesheet.
1868
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
1869

    
1870
            // Create a serializer, with output to the standard output stream
1871
            Serializer serializer = processor.NewSerializer();
1872
            serializer.SetOutputWriter(Console.Out);
1873
            serializer.SetOutputProperty(Serializer.INDENT, "yes");
1874

    
1875
            // Transform the source XML, calling a named initial template, and serialize the result document
1876
            transformer.CallTemplate(new QName("go"), serializer);
1877
        }
1878

    
1879
    }
1880

    
1881
    /// <summary>
1882
    /// Example extension function to compute a square root, using the simple API
1883
    /// </summary>
1884

    
1885
    public class SqrtSimple : ExtensionFunction
1886
    {
1887
        public XdmValue Call(XdmValue[] arguments)
1888
        {
1889
            if (!(arguments[0] is XdmEmptySequence))
1890
            {
1891
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].ItemAt(0);
1892
                double val = (double)arg.Value;
1893
                double sqrt = System.Math.Sqrt(val);
1894
                return new XdmAtomicValue(sqrt);
1895
            }
1896
            else
1897
            {
1898
                return XdmValue.MakeValue((double)0);
1899
            }
1900
        }
1901

    
1902
        public XdmSequenceType[] GetArgumentTypes()
1903
        {
1904
            return new XdmSequenceType[]{
1905
                new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
1906
            };
1907
        }
1908

    
1909
        public QName GetName()
1910
        {
1911
            return new QName("http://example.math.co.uk/demo", "sqrtSimple");
1912
        }
1913

    
1914
        public XdmSequenceType GetResultType()
1915
        {
1916
            return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), ' ');
1917
        }
1918
    }
1919

    
1920
    /// <summary>
1921
    /// Show a query producing a document as its result and serializing this to a FileStream
1922
    /// </summary>
1923

    
1924
    public class XQueryToStream : Example
1925
    {
1926

    
1927
        public override string testName
1928
        {
1929
            get { return "XQueryToStream"; }
1930
        }
1931

    
1932
        public override void run(Uri samplesDir)
1933
        {
1934
            Processor processor = new Processor(true);
1935
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1936
            compiler.BaseUri = samplesDir.ToString();
1937
            compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
1938
            XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>");
1939
            XQueryEvaluator eval = exp.Load();
1940
            Serializer qout = processor.NewSerializer();
1941
            qout.SetOutputProperty(Serializer.METHOD, "xml");
1942
            qout.SetOutputProperty(Serializer.INDENT, "yes");
1943
            qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1");
1944
            qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write));
1945
            Console.WriteLine("Output written to testoutput.xml");
1946
            eval.Run(qout);
1947
        }
1948

    
1949
    }
1950

    
1951
    /// <summary>
1952
    /// Show a query producing a single atomic value as its result and returning the value
1953
    /// to the C# application
1954
    /// </summary>
1955

    
1956
    public class XQueryToAtomicValue : Example
1957
    {
1958

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

    
1964
        public override void run(Uri samplesDir)
1965
        {
1966
            Processor processor = new Processor();
1967
            XQueryCompiler compiler = processor.NewXQueryCompiler();
1968
            XQueryExecutable exp = compiler.Compile("avg(for $i in 1 to 10 return $i * $i)");
1969
            XQueryEvaluator eval = exp.Load();
1970
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
1971
            Console.WriteLine("Result type: " + result.Value.GetType());
1972
            Console.WriteLine("Result value: " + (decimal)result.Value);
1973
        }
1974

    
1975
	}
1976

    
1977
	/// <summary>
1978
	/// Show a query producing a sequence as its result and returning the sequence
1979
	/// to the C# application in the form of an iterator. For each item in the
1980
	/// result, its string value is output.
1981
	/// </summary>
1982

    
1983
	public class XQueryToSequence : Example
1984
	{
1985

    
1986
		public override string testName
1987
		{
1988
			get { return "XQueryToSequence"; }
1989
		}
1990

    
1991
		public override void run(Uri samplesDir)
1992
		{
1993
			Processor processor = new Processor();
1994
			XQueryCompiler compiler = processor.NewXQueryCompiler();
1995
			XQueryExecutable exp = compiler.Compile("for $i in 1 to 10 return $i * $i");
1996
			XQueryEvaluator eval = exp.Load();
1997
			XdmValue value = eval.Evaluate();
1998
			foreach(XdmItem item in value)
1999
			{
2000
				Console.WriteLine(item.ToString());
2001
			}
2002

    
2003
		}
2004

    
2005
	}
2006

    
2007
    /// <summary>
2008
    /// Show a query producing a DOM as its input and producing a DOM as its output
2009
    /// </summary>
2010

    
2011
    public class XQueryToDom : Example
2012
    {
2013

    
2014
        public override string testName
2015
        {
2016
            get { return "XQueryToDom"; }
2017
        }
2018

    
2019
        public override void run(Uri samplesDir)
2020
        {
2021
            Processor processor = new Processor();
2022

    
2023
            XmlDocument input = new XmlDocument();
2024
            input.Load(new Uri(samplesDir, "data/books.xml").ToString());
2025
            XdmNode indoc = processor.NewDocumentBuilder().Build(new XmlNodeReader(input));
2026

    
2027
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2028
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
2029
            XQueryEvaluator eval = exp.Load();
2030
            eval.ContextItem = indoc;
2031
            DomDestination qout = new DomDestination();
2032
            eval.Run(qout);
2033
            XmlDocument outdoc = qout.XmlDocument;
2034
            Console.WriteLine(outdoc.OuterXml);
2035
        }
2036

    
2037
    }
2038

    
2039
    /// <summary>
2040
    /// Show a query producing a Saxon tree as its input and producing a Saxon tree as its output
2041
    /// </summary>
2042

    
2043
    public class XQueryToXdm : Example
2044
    {
2045

    
2046
        public override string testName
2047
        {
2048
            get { return "XQueryToXdm"; }
2049
        }
2050

    
2051
        public override void run(Uri samplesDir)
2052
        {
2053
            Processor processor = new Processor();
2054

    
2055
            DocumentBuilder loader = processor.NewDocumentBuilder();
2056
            loader.BaseUri = new Uri(samplesDir, "data/books.xml");
2057
            XdmNode indoc = loader.Build(loader.BaseUri);
2058

    
2059
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2060
            XQueryExecutable exp = compiler.Compile("<doc>{reverse(/*/*)}</doc>");
2061
            XQueryEvaluator eval = exp.Load();
2062
            eval.ContextItem = indoc;
2063
            XdmDestination qout = new XdmDestination();
2064
            eval.Run(qout);
2065
            XdmNode outdoc = qout.XdmNode;
2066
            Console.WriteLine(outdoc.OuterXml);
2067
        }
2068

    
2069
    }
2070

    
2071
    /// <summary>
2072
    /// Show a query making a direct call to a user-defined function defined in the query
2073
    /// </summary>
2074

    
2075
    public class XQueryCallFunction : Example
2076
    {
2077

    
2078
        public override string testName
2079
        {
2080
            get { return "XQueryCallFunction"; }
2081
        }
2082

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

    
2087
            XQueryCompiler qc = processor.NewXQueryCompiler();
2088
            Uri uri = new Uri(samplesDir, "data/books.xml");
2089
            XQueryExecutable exp1 = qc.Compile("declare namespace f='f.ns';" +
2090
                   "declare variable $z := 1 + xs:integer(doc-available('" + uri.ToString() + "'));" +
2091
                   "declare variable $p as xs:integer external;" +
2092
                   "declare function f:t1($v1 as xs:integer) { " +
2093
                   "   $v1 div $z + $p" +
2094
                   "};" +
2095
                   "10");
2096
            XQueryEvaluator ev = exp1.Load();
2097
            ev.SetExternalVariable(new QName("", "p"), new XdmAtomicValue(39));
2098
            XdmValue v1 = new XdmAtomicValue(10);
2099
            XdmValue result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2100
            Console.WriteLine("First result (expected 44): " + result.ToString());
2101
            v1 = new XdmAtomicValue(20);
2102
            result = ev.CallFunction(new QName("f.ns", "f:t1"), new XdmValue[] { v1 });
2103
            Console.WriteLine("Second result (expected 49): " + result.ToString());
2104
        }
2105

    
2106
    }
2107

    
2108
    /// <summary>
2109
    /// Show a query reading an input document using an XmlReader (the .NET XML parser)
2110
    /// </summary>
2111

    
2112
    public class XQueryFromXmlReader : Example
2113
    {
2114

    
2115
        public override string testName
2116
        {
2117
            get { return "XQueryFromXmlReader"; }
2118
        }
2119

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

    
2124
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2125
            XmlTextReader reader = new XmlTextReader(inputFileName,
2126
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2127
            reader.Normalization = true;
2128

    
2129
            // Add a validating reader - needed in case there are entity references
2130
            XmlReaderSettings settings = new XmlReaderSettings();
2131
            settings.ValidationType = ValidationType.DTD;
2132
            settings.DtdProcessing = DtdProcessing.Parse;
2133
            XmlReader validator = XmlReader.Create(reader, settings);
2134

    
2135
            XdmNode doc = processor.NewDocumentBuilder().Build(validator);
2136

    
2137
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2138
            XQueryExecutable exp = compiler.Compile("/");
2139
            XQueryEvaluator eval = exp.Load();
2140
            eval.ContextItem = doc;
2141
            Serializer qout = processor.NewSerializer();
2142
            qout.SetOutputProperty(Serializer.METHOD, "xml");
2143
            qout.SetOutputProperty(Serializer.INDENT, "yes");
2144
            qout.SetOutputStream(new FileStream("testoutput2.xml", FileMode.Create, FileAccess.Write));
2145
            Console.WriteLine("Output written to testoutput2.xml");
2146
            eval.Run(qout);
2147
        }
2148

    
2149
    }
2150

    
2151
    /// <summary>
2152
    /// Show a query producing a sequence as its result and returning the sequence
2153
    /// to the C# application in the form of an iterator. The sequence is then
2154
    /// output by serializing each item individually, with each item on a new line.
2155
    /// </summary>
2156

    
2157
    public class XQueryToSerializedSequence : Example
2158
    {
2159

    
2160
        public override string testName
2161
        {
2162
            get { return "XQueryToSerializedSequence"; }
2163
        }
2164

    
2165
        public override void run(Uri samplesDir)
2166
        {
2167
            Processor processor = new Processor();
2168
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2169
            XmlTextReader reader = new XmlTextReader(inputFileName,
2170
                UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")));
2171
            reader.Normalization = true;
2172

    
2173
            // Add a validating reader - needed in case there are entity references
2174
            XmlReaderSettings settings = new XmlReaderSettings();
2175
            settings.ValidationType = ValidationType.DTD;
2176
            settings.DtdProcessing = DtdProcessing.Parse;
2177
            XmlReader validator = XmlReader.Create(reader, settings);
2178

    
2179
            XdmNode doc = processor.NewDocumentBuilder().Build(reader);
2180

    
2181
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2182
            XQueryExecutable exp = compiler.Compile("//ISBN");
2183
            XQueryEvaluator eval = exp.Load();
2184
            eval.ContextItem = doc;
2185

    
2186
            foreach (XdmNode node in eval)
2187
            {
2188
                Console.WriteLine(node.OuterXml);
2189
            }
2190
        }
2191

    
2192
    }
2193

    
2194
    /// <summary>
2195
    /// Show a query that takes a parameter (external variable) as input.
2196
    /// The query produces a single atomic value as its result and returns the value
2197
    /// to the C# application. 
2198
    /// </summary>
2199

    
2200
    public class XQueryUsingParameter : Example
2201
    {
2202

    
2203
        public override string testName
2204
        {
2205
            get { return "XQueryUsingParameter"; }
2206
        }
2207

    
2208
        public override void run(Uri samplesDir)
2209
        {
2210
            Processor processor = new Processor();
2211
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2212
            compiler.DeclareNamespace("p", "http://saxon.sf.net/ns/p");
2213
            XQueryExecutable exp = compiler.Compile(
2214
                    "declare variable $p:in as xs:integer external; $p:in * $p:in");
2215
            XQueryEvaluator eval = exp.Load();
2216
            eval.SetExternalVariable(new QName("http://saxon.sf.net/ns/p", "p:in"), new XdmAtomicValue(12));
2217
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2218
            Console.WriteLine("Result type: " + result.Value.GetType());
2219
            Console.WriteLine("Result value: " + (long)result.Value);
2220
        }
2221

    
2222
    }
2223

    
2224
    /// <summary>
2225
    /// Show a query consisting of two modules, using a QueryResolver to resolve
2226
    /// the "import module" declaration
2227
    /// </summary>
2228

    
2229
    public class XQueryMultiModule : Example
2230
    {
2231

    
2232
        public override string testName
2233
        {
2234
            get { return "XQueryMultiModule"; }
2235
        }
2236

    
2237
        public override void run(Uri samplesDir)
2238
        {
2239

    
2240
            String mod1 = "import module namespace m2 = 'http://www.example.com/module2';" +
2241
                          "m2:square(3)";
2242

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

    
2246
            Processor processor = new Processor();
2247
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2248

    
2249
            InlineModuleResolver resolver = new InlineModuleResolver();
2250
            resolver.AddModule(new Uri("http://www.example.com/module2"), mod2);
2251
            compiler.QueryResolver = resolver;
2252
            XQueryExecutable exp = compiler.Compile(mod1);
2253
            XQueryEvaluator eval = exp.Load();
2254

    
2255
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2256
            Console.WriteLine("Result type: " + result.Value.GetType());
2257
            Console.WriteLine("Result value: " + (long)result.Value);
2258
        }
2259

    
2260
        // A simple QueryResolver designed to show that the actual query
2261
        // text can come from anywhere: in this case, the resolver maintains
2262
        // a simple mapping of module URIs onto strings.
2263

    
2264
        public class InlineModuleResolver : IQueryResolver
2265
        {
2266

    
2267
            private Hashtable modules = new Hashtable();
2268

    
2269
            public void AddModule(Uri moduleName, String moduleText)
2270
            {
2271
                modules.Add(moduleName, moduleText);
2272
            }
2273

    
2274
            public Uri[] GetModules(String moduleUri, Uri baseUri, String[] locationHints)
2275
            {
2276
                Uri[] result = { new Uri(moduleUri) };
2277
                return result;
2278
            }
2279

    
2280
            public Object GetEntity(Uri absoluteUri)
2281
            {
2282
                return modules[absoluteUri];
2283
            }
2284
        }
2285

    
2286
    }
2287

    
2288
    /// <summary>
2289
    /// Demonstrate using a try-catch expression in the query, a feature of XQuery 3.0
2290
    /// </summary>
2291

    
2292
    public class XQueryTryCatch : Example
2293
    {
2294

    
2295
        public override string testName
2296
        {
2297
            get { return "XQueryTryCatch"; }
2298
        }
2299

    
2300
        public override void run(Uri samplesDir)
2301
        {
2302

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

    
2306
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2307
            compiler.XQueryLanguageVersion = "3.0";
2308
            XQueryExecutable exp = compiler.Compile(query);
2309
            XQueryEvaluator eval = exp.Load();
2310
            Serializer qout = processor.NewSerializer(Console.Out);
2311
            eval.Run(qout);
2312
        }
2313

    
2314
    }
2315

    
2316
    /// <summary>
2317
    /// Demonstrate XQuery extensibility using user-written reflexive extension functions
2318
    /// </summary>
2319
    /// <remarks>Note: If SamplesExtensions is compiled to a different assembly than ExamplesEE, use 
2320
    /// the namespace URI clitype:SampleExtensions.SampleExtensions?asm=ASSEMBLY_NAME_HERE
2321
    /// Alternatively, the location of an assembly can be provided as a URI using the 'from' keyword
2322
    /// e.g. clitype:SampleExtensions.SampleExtensions?from=file:///c:/lib/SampleExtensions.dll
2323
    /// </remarks>
2324

    
2325
    public class XQueryExtensibility : Example
2326
    {
2327

    
2328
        public override string testName
2329
        {
2330
            get { return "XQueryExtensibility"; }
2331
        }
2332

    
2333
        public override void run(Uri samplesDir)
2334
        {
2335
            String query =
2336
                "declare namespace ext = \"clitype:SampleExtensions.SampleExtensions?asm=ExamplesEE\";" +
2337
                "<out>" +
2338
                "  <addition>{ext:add(2,2)}</addition>" +
2339
                "  <average>{ext:average((1,2,3,4,5,6))}</average>" +
2340
                "  <language>{ext:hostLanguage()}</language>" +
2341
                "</out>";
2342

    
2343
            Processor processor = new Processor(true);
2344
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2345
            XQueryExecutable exp = compiler.Compile(query);
2346
            XQueryEvaluator eval = exp.Load();
2347
            Serializer qout = processor.NewSerializer(Console.Out);
2348
            eval.Run(qout);
2349
        }
2350

    
2351
    }
2352

    
2353
    /// <summary>
2354
    /// Demonstrate XQuery Update
2355
    /// </summary>
2356

    
2357
    public class XQueryUpdate : Example
2358
    {
2359

    
2360
        public override string testName
2361
        {
2362
            get { return "XQueryUpdate"; }
2363
        }
2364

    
2365
        public override void run(Uri samplesDir)
2366
        {
2367
            Processor processor = new Processor(true);
2368

    
2369
            DocumentBuilder loader = processor.NewDocumentBuilder();
2370
            loader.BaseUri = new Uri(samplesDir, "data/books.xml");
2371
            loader.TreeModel = TreeModel.LinkedTree;
2372
            XdmNode indoc = loader.Build(new Uri(samplesDir, "data/books.xml"));
2373

    
2374
            Console.Out.WriteLine("=========== BEFORE UPDATE ===========");
2375

    
2376
            Serializer serializer0 = processor.NewSerializer();
2377
            serializer0.SetOutputProperty(Serializer.METHOD, "xml");
2378
            serializer0.SetOutputProperty(Serializer.INDENT, "yes");
2379
            serializer0.SetOutputWriter(Console.Out);
2380
            processor.WriteXdmValue(indoc, serializer0);
2381

    
2382
            String query =
2383
                "for $i in //PRICE return \n" +
2384
                "replace value of node $i with $i - 0.05";
2385

    
2386
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2387
            compiler.UpdatingEnabled = true;
2388
            XQueryExecutable exp = compiler.Compile(query);
2389
            XQueryEvaluator eval = exp.Load();
2390
            eval.ContextItem = indoc;
2391
            XdmNode[] updatedNodes = eval.RunUpdate();
2392

    
2393
            // Serialize the updated result to Console.out
2394
            foreach (XdmNode root in updatedNodes)
2395
            {
2396
                Uri documentUri = root.DocumentUri;
2397
                if (documentUri != null && documentUri.Scheme == "file")
2398
                {
2399
                    Serializer serializer = processor.NewSerializer();
2400
                    serializer.SetOutputProperty(Serializer.METHOD, "xml");
2401
                    serializer.SetOutputProperty(Serializer.INDENT, "yes");
2402
                    Console.Out.WriteLine("=========== AFTER UPDATE ===========");
2403
                    serializer.SetOutputWriter(Console.Out);
2404
                    processor.WriteXdmValue(root, serializer);
2405
                }
2406
            }
2407

    
2408
			// To serialize to the original source file, replace the above code with the following
2409

    
2410
			//foreach (XdmNode root in updatedNodes)
2411
			//{
2412
			//	Uri documentUri = root.DocumentUri;
2413
			//	if (documentUri != null && documentUri.Scheme == "file")
2414
			//	{
2415
			//		Stream stream = UriConnection.getWritableUriStream(documentUri);
2416
			//		Serializer serializer = processor.NewSerializer();
2417
			//		serializer.SetOutputProperty(Serializer.METHOD, "xml");
2418
			//		serializer.SetOutputProperty(Serializer.INDENT, "yes");
2419
			//		serializer.SetOutputStream(stream);
2420
			//		processor.WriteXdmValue(root, serializer);
2421
			//	}
2422
			//}
2423
			//
2424
			//Console.Out.WriteLine("=========== AFTER UPDATE ===========");
2425
			//
2426
			//processor.WriteXdmValue(indoc, serializer0);
2427
        }
2428
	}
2429

    
2430
    /// <summary>
2431
    /// Demonstrate schema aware XQuery
2432
    /// </summary>
2433

    
2434
    public class XQuerySchemaAware : Example
2435
    {
2436

    
2437
        public override string testName
2438
        {
2439
            get { return "XQuerySchemaAware"; }
2440
        }
2441

    
2442
        public override void run(Uri samplesDir)
2443
        {
2444
            Processor processor = new Processor(true);
2445

    
2446
            String inputFileName = new Uri (samplesDir, "data/books.xml").ToString();
2447
            String inputSchemaName = new Uri (samplesDir, "data/books.xsd").ToString();
2448
            String query = "import schema default element namespace \"\" at \"" + inputSchemaName + "\";\n" +
2449
                "for $integer in (validate { doc(\"" + inputFileName + "\") })//schema-element(ITEM)\n" +
2450
                "return <OUTPUT>{$integer}</OUTPUT>";
2451

    
2452
            XQueryCompiler compiler = processor.NewXQueryCompiler();
2453
            compiler.XQueryLanguageVersion = "1.0";
2454
            XQueryExecutable exp = compiler.Compile(query);
2455
            XQueryEvaluator eval = exp.Load();
2456
            Serializer qout = processor.NewSerializer(Console.Out);
2457
            qout.SetOutputProperty(Serializer.METHOD, "xml");
2458
            qout.SetOutputProperty(Serializer.INDENT, "yes");
2459
            eval.Run(qout);
2460
        }
2461

    
2462
    }
2463

    
2464
    /// <summary>
2465
    /// Demonstrate schema aware XPath
2466
    /// </summary>
2467

    
2468
    public class XPathSchemaAware : Example
2469
    {
2470

    
2471
        public override string testName
2472
        {
2473
            get { return "XPathSchemaAware"; }
2474
        }
2475

    
2476
        public override void run(Uri samplesDir)
2477
        {
2478
            Processor processor = new Processor(true);
2479

    
2480

    
2481
            String inputFileName = new Uri(samplesDir, "data/books.xml").ToString();
2482

    
2483
            processor.SchemaManager.Compile(new Uri(samplesDir, "data/books.xsd"));
2484

    
2485
            // Add a reader
2486
            XmlReaderSettings settings = new XmlReaderSettings();
2487
            settings.DtdProcessing = DtdProcessing.Ignore;
2488
            XmlReader xmlReader = XmlReader.Create(UriConnection.getReadableUriStream(new Uri(samplesDir, "data/books.xml")), settings);
2489

    
2490
            DocumentBuilder builder = processor.NewDocumentBuilder();
2491

    
2492
            builder.SchemaValidationMode = SchemaValidationMode.Strict;
2493
            XdmNode doc = builder.Build(xmlReader);
2494

    
2495
            XPathCompiler compiler = processor.NewXPathCompiler();
2496
            compiler.ImportSchemaNamespace("");
2497
            XPathExecutable exp = compiler.Compile("if (//ITEM[@CAT='MMP']/QUANTITY instance of element(*,xs:integer)*) then 'true' else 'false'");
2498
            XPathSelector eval = exp.Load();
2499
            eval.ContextItem = doc;
2500
            XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle();
2501
            Console.WriteLine("Result type: " + result.ToString());
2502
        }
2503

    
2504
    }
2505

    
2506
    /// <summary>
2507
    /// Show XSLT streaming of document
2508
    /// </summary>
2509

    
2510
    public class XsltStreamDoc : Example
2511
    {
2512

    
2513
        public override string testName
2514
        {
2515
            get { return "XsltStreamDoc"; }
2516
        }
2517

    
2518
        public override void run(Uri samplesDir)
2519
        {
2520
            Processor processor = new Processor(true);
2521

    
2522
            // Create the stylesheet
2523
            String s = "<xsl:transform version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>\n" +
2524
				" <xsl:template name='main'>\n" +
2525
				"  <xsl:source-document streamable='yes' href='" + new Uri(samplesDir, "data/othello.xml").ToString() + "'>\n" +
2526
				"   <xsl:value-of select=\"count(copy-of(//LINE)[count(tokenize(.)) &gt; 0] )\" />\n" +
2527
				"  </xsl:source-document>\n"+
2528
				" </xsl:template>\n" +
2529
				"</xsl:transform>";
2530

    
2531
            // Create a transformer for the stylesheet.
2532
            Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(new StringReader(s)).Load30();
2533

    
2534
            // Create a serializer, with output to the standard output stream
2535
            Serializer serializer = processor.NewSerializer();
2536
            serializer.SetOutputWriter(Console.Out);
2537
            //  serializer.SetOutputProperty(Serializer.INDENT, "yes");
2538

    
2539
            // Transform the source XML, calling a named initial template, and serialize the result document.
2540
            transformer.CallTemplate(new QName("main"), serializer);
2541
        }
2542

    
2543
    }
2544

    
2545
    /// <summary>
2546
    /// Show validation of an instance document against a schema, 
2547
    /// if the document is valid then run a schema aware query
2548
    /// </summary>
2549

    
2550
    public class Validate : Example
2551
    {
2552

    
2553
        public override string testName
2554
        {
2555
            get { return "Validate"; }
2556
        }
2557

    
2558
        public override void run(Uri samplesDir)
2559
        {
2560
            // Load a schema
2561

    
2562
            Processor processor = new Processor(true);
2563
            processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
2564
            processor.SetProperty("http://saxon.sf.net/feature/validation-warnings", "false"); //Set to true to suppress the exception
2565
            SchemaManager manager = processor.SchemaManager;
2566
            manager.XsdVersion = "1.1";
2567
            manager.ErrorList = new List<StaticError>();
2568
            Uri schemaUri = new Uri(samplesDir, "data/books.xsd");
2569

    
2570
            try
2571
            {
2572
                manager.Compile(schemaUri);
2573
            }
2574
            catch (Exception e)
2575
            {
2576
                Console.WriteLine(e);
2577
                Console.WriteLine("Schema compilation failed with " + manager.ErrorList.Count + " errors");
2578
                foreach (StaticError error in manager.ErrorList)
2579
                {
2580
                    Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
2581
                }
2582
                return;
2583
            }
2584

    
2585

    
2586
            // Use this to validate an instance document
2587

    
2588
            SchemaValidator validator = manager.NewSchemaValidator();
2589

    
2590
            XmlReaderSettings settings = new XmlReaderSettings();
2591
            settings.DtdProcessing = DtdProcessing.Ignore;
2592
            String inputFileName = new Uri(samplesDir, "data/books-invalid.xml").ToString();
2593
            XmlReader xmlReader = XmlReader.Create(inputFileName, settings);
2594
            validator.SetSource(xmlReader);
2595
            Console.WriteLine("Validating input file " + inputFileName);
2596
            validator.ErrorList = new List<ValidationFailure>();
2597
            XdmDestination psvi = new XdmDestination();
2598
            validator.SetDestination(psvi);
2599

    
2600
            try
2601
            {
2602
                validator.Run();
2603
            }
2604
            catch (Exception e)
2605
            {
2606
                Console.WriteLine(e);
2607
                Console.WriteLine("Instance validation failed with " + validator.ErrorList.Count + " errors");
2608
                foreach (ValidationFailure error in validator.ErrorList)
2609
                {
2610
                    Console.WriteLine("At line " + error.GetLineNumber() + ": " + error.GetMessage());
2611
                }
2612
                return;
2613
            }
2614

    
2615
            Console.WriteLine("Input file is valid");
2616

    
2617
            // Run a query on the result to check that it has type annotations
2618

    
2619
            XQueryCompiler xq = processor.NewXQueryCompiler();
2620
            xq.SchemaAware = true;
2621
            XQueryEvaluator xv = xq.Compile("data((//PRICE)[1]) instance of xs:decimal").Load();
2622
            xv.ContextItem = psvi.XdmNode;
2623
            Console.WriteLine("Price is decimal? " + xv.EvaluateSingle().ToString());
2624
        }
2625
    }
2626

    
2627

    
2628
    public class UriConnection
2629
    {
2630

    
2631
        // Get a stream for reading from a file:// URI
2632

    
2633
        public static Stream getReadableUriStream(Uri uri)
2634
        {
2635
            WebRequest request = (WebRequest)WebRequest.Create(uri);
2636
            return request.GetResponse().GetResponseStream();
2637
        }
2638

    
2639
        // Get a stream for writing to a file:// URI
2640

    
2641
        public static Stream getWritableUriStream(Uri uri)
2642
        {
2643
            FileWebRequest request = (FileWebRequest)WebRequest.CreateDefault(uri);
2644
            request.Method = "POST";
2645
            return request.GetRequestStream();
2646
        }
2647
    }
2648

    
2649
    ///
2650
    /// A sample XmlResolver. In the case of a URI ending with ".txt", it returns the
2651
    /// URI itself, wrapped as an XML document. In the case of the URI "empty.xslt", it returns an empty
2652
    /// stylesheet. In all other cases, it returns null, which has the effect of delegating
2653
    /// processing to the standard XmlResolver.
2654
    ///
2655

    
2656
    public class UserXmlResolver : XmlUrlResolver
2657
    {
2658

    
2659
        public String Message = null;
2660

    
2661
        public override object GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
2662
        {
2663
            if (Message != null)
2664
            {
2665
                Console.WriteLine(Message + absoluteUri + " (role=" + role + ")");
2666
            }
2667

    
2668
            if (absoluteUri.ToString().EndsWith(".txt"))
2669
            {
2670
                MemoryStream ms = new MemoryStream();
2671
                StreamWriter tw = new StreamWriter(ms);
2672
                tw.Write("<uri>");
2673
                tw.Write(absoluteUri);
2674
                tw.Write("</uri>");
2675
                tw.Flush();
2676
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2677
            }
2678
            if (absoluteUri.ToString().EndsWith("empty.xslt"))
2679
            {
2680
                String ss = "<transform xmlns='http://www.w3.org/1999/XSL/Transform' version='2.0'/>";
2681
                MemoryStream ms = new MemoryStream();
2682
                StreamWriter tw = new StreamWriter(ms);
2683
                tw.Write(ss);
2684
                tw.Flush();
2685
                return new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
2686
            }
2687
            else
2688
            {
2689
                return null;
2690
            }
2691
        }
2692
    }
2693

    
2694
    public class UserResultDocumentHandler : IResultDocumentHandler
2695
    {
2696

    
2697
        private Hashtable results;
2698

    
2699
        public UserResultDocumentHandler(Hashtable table)
2700
        {
2701
            this.results = table;
2702
        }
2703

    
2704
        public XmlDestination HandleResultDocument(string href, Uri baseUri)
2705
        {
2706
            DomDestination destination = new DomDestination();
2707
            results[href] = destination;
2708
            return destination;
2709
        }
2710

    
2711
    }
2712
}
2713

    
2714

    
2715
//
2716
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
2717
// you may not use this file except in compliance with the License. You may obtain a copy of the
2718
// License at http://www.mozilla.org/MPL/
2719
//
2720
// Software distributed under the License is distributed on an "AS IS" basis,
2721
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
2722
// See the License for the specific language governing rights and limitations under the License.
2723
//
2724
// The Original Code is: all this file.
2725
//
2726
// The Initial Developer of the Original Code is Michael H. Kay.
2727
//
2728
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
2729
//
2730
// Contributor(s): none.
2731
//
2732

    
2733

    
(1-1/5)