Project

Profile

Help

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

he / src / samples / cs / TestRunner10.0 / XsltTestSuiteDriver.cs @ be17ef52

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

    
9
/// <summary>
10
/// This is the test suite driver for running the W3C XSLT test suite against Saxon on .NET.
11
/// Note that the W3C XSLT test suite at the time of writing is available to W3C members only.
12
/// </summary>
13
/// <remarks>
14
/// <para>Before running, carry out the following steps:</para>
15
/// <para>1. Create a subdirectory SaxonResults.net within TestSuiteStagingArea</para>
16
/// <para>2. Copy compare.xsl from samples/styles into that subdirectory</para>
17
/// <para>3. Create a subdirectory SaxonResults within TestSuiteStagingArea</para>
18
/// <para>4. Create a file exceptions.xml within that subdirectory listing tests that
19
/// are not to be run (with a reason). Specimen format
20
/// as follows:</para>
21
/// <para><![CDATA[
22
/// <testcase-exceptions xmlns="http://www.w3.org/2005/05/xslt20-test-catalog">
23
///   <exception>
24
///     <testcase name="atrs24">
25
///       <comment>Expected result wrong, bug 700</comment>
26
///     </testcase>
27
///   </exception>
28
/// </testcase-exceptions>
29
/// ]]></para>
30
/// <para>TODO: use a different exceptions file for .NET, to exclude tests that rely on
31
/// features such as id() support.</para>
32
/// </remarks>
33

    
34

    
35
public class XsltTestSuiteDriver
36
{
37
    static void MainXXX(string[] args)
38
    {
39
        if (args.Length == 0 || args[0].Equals("-?"))
40
        {
41
            Console.WriteLine("XsltTestSuiteDriver testsuiteDir testName?");
42
        }
43

    
44
        new XsltTestSuiteDriver().go(args);
45
    }
46

    
47
    String testSuiteDir;
48
    Processor processor = new Processor();    
49
    Processor schemaAwareProcessor; /* = new Processor(true); */
50
    IFeedbackListener feedback;
51
    FileComparer fileComparer;
52

    
53
    string testPattern = null;
54
    bool xml11 = false;
55

    
56
    StreamWriter results;
57
    StreamWriter log;
58

    
59
    
60

    
61
    /**
62
     * Some tests use schemas that conflict with others, so they can't use the common schema cache.
63
     * These tests are run in a Configuration of their own. (Ideally we would put this list in a
64
     * catalogue file of some kind).
65
     */
66
    
67
        static Hashtable noCacheTests = new Hashtable(30); // HashSet is available in .NET 3.5 and later
68
        static XsltTestSuiteDriver() {
69
            noCacheTests.Add("schemaas20_002_01", true);
70
            noCacheTests.Add("schemaas20_011_02", true);
71
            noCacheTests.Add("schemaas20_025_01", true);
72
            noCacheTests.Add("schemaas20_028_02", true);
73
            noCacheTests.Add("schemaas20_038_02", true);
74
            noCacheTests.Add("schemaas20_041_02", true);
75
            noCacheTests.Add("schemaas20_044_02", true);
76
            noCacheTests.Add("schemaas20_050_02", true);
77
            noCacheTests.Add("schemaas20_109_01", true);
78
            noCacheTests.Add("schemaas20_111_01", true);
79
            noCacheTests.Add("schemaas20_115_01", true);
80
            noCacheTests.Add("schemaas20_116_01", true);
81
            noCacheTests.Add("schemaas20_121_01", true);
82
            noCacheTests.Add("schemaas20_125_01", true);
83
            noCacheTests.Add("schemaas20_157_01", true);
84
            noCacheTests.Add("schemaas20_161_01", true);
85
            noCacheTests.Add("schemaas20_209_01", true);
86
            noCacheTests.Add("schemaas20_221_01", true);
87
            noCacheTests.Add("schemaas20_225_01", true);
88
            noCacheTests.Add("schemaas20_226_01", true);
89
            noCacheTests.Add("schemaas20_228_01", true);
90
            noCacheTests.Add("schemaas20_242_01", true);
91
            noCacheTests.Add("schemaas20_255_01", true);
92
            noCacheTests.Add("schemaas20_260_01", true);
93
            noCacheTests.Add("schemaas20_274_01", true);
94
            noCacheTests.Add("schemaas20_292_01", true);
95
            noCacheTests.Add("schemaas20_332_01", true);
96
            noCacheTests.Add("schema092", true);
97
            noCacheTests.Add("schemainline20_005_01", true);
98
            noCacheTests.Add("schemamatch20_001_01", true);
99
            noCacheTests.Add("schemamatch20_003_01", true);
100
            noCacheTests.Add("schemamatch20_005_01", true);
101
            noCacheTests.Add("schemamatch20_007_01", true);
102
            noCacheTests.Add("schemamatch20_036_01", true);
103
            noCacheTests.Add("schemamatch20_038_01", true);
104
            noCacheTests.Add("schemamatch20_061_01", true);
105
            noCacheTests.Add("schemamatch20_079_01", true);
106
            noCacheTests.Add("schemamatch20_092_01", true);
107
            noCacheTests.Add("schemamatch20_123_01", true);
108
            noCacheTests.Add("schemamatch20_140_01", true);
109
            noCacheTests.Add("schemanodetest20_001_01", true);
110
            noCacheTests.Add("schemanodetest20_023_01", true);
111
            noCacheTests.Add("schvalid001", true);
112
            noCacheTests.Add("schvalid009", true);
113
            noCacheTests.Add("schvalid014", true);
114
            noCacheTests.Add("schvalid015", true);
115
            noCacheTests.Add("schvalid020", true);
116
            noCacheTests.Add("striptype20_003_01", true);
117
            noCacheTests.Add("striptype20_006_01", true);
118
            noCacheTests.Add("striptype20_008_01", true);
119
            noCacheTests.Add("striptype20_011_01", true);
120
            noCacheTests.Add("striptype20_012_01", true);
121
            noCacheTests.Add("striptype20_028_01", true);
122
            noCacheTests.Add("striptype20_039_01", true);
123

    
124
        }
125
    
126

    
127
    public void setFeedbackListener(IFeedbackListener f) {
128
        feedback = f;
129
    }
130

    
131
    private XdmNode getChildElement(XdmNode parent, QName child)
132
    {
133
        IEnumerator e = parent.EnumerateAxis(XdmAxis.Child, child);
134
        return e.MoveNext() ? (XdmNode)e.Current : null;
135
    }
136

    
137

    
138
    public void go(String[] args)
139
    {
140
        int passed = 0;
141
        int failed = 0;
142
        int total = 0;
143

    
144
        
145
        testSuiteDir = args[0];
146
        if (testSuiteDir.EndsWith("/"))
147
        {
148
            testSuiteDir = testSuiteDir.Substring(0, testSuiteDir.Length - 1);
149
        }
150
        Hashtable exceptions = new Hashtable();
151

    
152
        if (args.Length > 1)
153
        {
154
            testPattern = (args[1]); 
155
        }
156

    
157
        for (int i = 0; i < args.Length; i++)
158
        {
159
            if (args[i].Equals("-w"))
160
            {
161
                //showWarnings = true;
162
            }
163
        }
164

    
165
        try
166
        {
167
            schemaAwareProcessor = new Processor(true);
168
        }
169
        catch (Exception)
170
        {
171
            Console.WriteLine("Cannot load Saxon-SA: continuing without it");
172
        }
173

    
174
        processor.SetProperty("http://saxon.sf.net/feature/preferJaxpParser", "true");
175

    
176
        if (schemaAwareProcessor != null)
177
        {
178
            schemaAwareProcessor.SetProperty("http://saxon.sf.net/feature/preferJaxpParser", "true");
179
        }
180
        fileComparer = new FileComparer(processor, testSuiteDir);
181

    
182
        String testURI = "http://www.w3.org/2005/05/xslt20-test-catalog";
183

    
184
        QName testCaseNT = new QName(testURI, "testcase");
185
        QName nameNT = new QName(testURI, "name");
186
        QName inputNT = new QName(testURI, "input");
187
        QName outputNT = new QName(testURI, "output");
188
        QName stylesheetNT = new QName(testURI, "stylesheet");
189
        QName schemaNT = new QName(testURI, "schema");
190
        QName initialModeNT = new QName(testURI, "initial-mode");
191
        QName entryNamedTemplateNT = new QName(testURI, "entry-named-template");
192
        QName sourceDocumentNT = new QName(testURI, "source-document");
193
        QName stylesheetParametersNT = new QName(testURI, "stylesheet-parameters");
194
        QName paramNT = new QName(testURI, "param");
195
        QName resultDocumentNT = new QName(testURI, "result-document");
196
        QName errorNT = new QName(testURI, "error");
197
        QName validationNT = new QName(testURI, "validation");
198
        QName discretionaryItemsNT = new QName(testURI, "discretionary-items");
199
        QName discretionaryFeatureNT = new QName(testURI, "discretionary-feature");
200
        QName discretionaryChoiceNT = new QName(testURI, "discretionary-choice");
201
        QName discretionaryVersionNT = new QName(testURI, "discretionary-version");
202
        QName initialContextNodeNT = new QName(testURI, "initial-context-node");
203

    
204

    
205
        QName fileAtt = new QName("", "file");
206
        QName errorIdAtt = new QName("", "error-id");
207
        QName typeAtt = new QName("", "type");
208
        QName nameAtt = new QName("", "name");
209
        QName behaviorAtt = new QName("", "behavior");
210
        QName specAtt = new QName("", "spec");
211
        QName qnameAtt = new QName("", "qname");
212
        QName modeAtt = new QName("", "mode");
213
        QName validatesAtt = new QName("", "validates");
214
        QName roleAtt = new QName("", "role");
215

    
216
        DocumentBuilder builder = processor.NewDocumentBuilder();
217
        XdmNode exceptionsDoc = builder.Build(new Uri(testSuiteDir + '/' + getResultDirectoryName() + "/exceptions.xml"));
218

    
219
        IEnumerator exceptionTestCases = exceptionsDoc.EnumerateAxis(XdmAxis.Descendant, testCaseNT);
220
        while (exceptionTestCases.MoveNext())
221
        {
222
            XdmNode n = (XdmNode)exceptionTestCases.Current;
223
            String nameAttVal = n.GetAttributeValue(nameAtt);
224
            char[] seps = { ' ', '\n', '\t' };
225
            String[] parts = nameAttVal.Split(seps);
226
            foreach (string p in parts)
227
            {
228
                if (!exceptions.ContainsKey(p))
229
                {
230
                    exceptions.Add(p, "Kilroy");
231
                }
232
            }
233
        }
234

    
235
        XdmNode catalog = builder.Build(new Uri(testSuiteDir + "/catalog.xml"));
236

    
237
        results = new StreamWriter(testSuiteDir + "/SaxonResults.net/results"
238
                    + processor.ProductVersion + ".xml");
239
        log = new StreamWriter(testSuiteDir + "/SaxonResults.net/log"
240
                    + processor.ProductVersion + "n.xml");
241
        log.WriteLine("Testing Saxon " + processor.ProductVersion);
242

    
243
        results.WriteLine("<test-suite-result>");
244
        results.WriteLine(" <implementation name='Saxon-SA' version='" + processor.ProductVersion +
245
                "' anonymous-result-column='false'>");
246
        results.WriteLine("  <organization name='http://www.saxonica.com/' anonymous='false'/>");
247
        results.WriteLine("  <submitter name='Michael Kay' email='mike@saxonica.com'/>");
248
        outputDiscretionaryItems();
249
        results.WriteLine(" </implementation>");
250

    
251
        total = 0;
252
        IEnumerator testCases = catalog.EnumerateAxis(XdmAxis.Descendant, testCaseNT);
253
        while (testCases.MoveNext())
254
        {
255
            total++;
256
        }
257

    
258
        testCases = catalog.EnumerateAxis(XdmAxis.Descendant, testCaseNT);
259
        while (testCases.MoveNext())
260
        {
261
            bool useAssociated = false;
262
            XdmNode testCase = (XdmNode)testCases.Current;
263

    
264
            String testName = getChildElement(testCase, nameNT).StringValue;
265
            if (testPattern != null && !testName.StartsWith(testPattern))
266
            {
267
                continue;
268
            }
269
            if (exceptions.ContainsKey(testName))
270
            {
271
                continue;
272
            }
273
            if (isExcluded(testName))
274
            {
275
                continue;
276
            }
277
            log.WriteLine("Test " + testName);
278
            XdmNode testInput = getChildElement(testCase, inputNT);
279

    
280
            XdmNode stylesheet = getChildElement(testInput, stylesheetNT);
281
            String absXSLName = null;
282
            if (stylesheet == null)
283
            {
284
                useAssociated = true;
285
            }
286
            else
287
            {
288
                absXSLName = testSuiteDir + "/TestInputs/" + stylesheet.GetAttributeValue(fileAtt);
289
            }
290

    
291
            XdmNode sourceDocument = getChildElement(testInput, sourceDocumentNT);
292
            String absXMLName = null;
293
            if (sourceDocument != null)
294
            {
295
                absXMLName = testSuiteDir + "/TestInputs/" + sourceDocument.GetAttributeValue(fileAtt);
296
            }
297

    
298
            bool schemaAware = false;
299
            bool recoverRecoverable = true;
300
            bool backwardsCompatibility = true;
301
            bool supportsDOE = true;
302
            bool recoverSESU0007 = false;
303
            bool useXSLT30 = false;
304
            XdmNode discretionaryItems = getChildElement(testCase, discretionaryItemsNT);
305
            if (discretionaryItems != null)
306
            {
307
                IEnumerator features = discretionaryItems.EnumerateAxis(XdmAxis.Child, discretionaryFeatureNT);
308
                while (features.MoveNext())
309
                {
310
                    XdmNode feature = (XdmNode)features.Current;
311
                    String featureName = feature.GetAttributeValue(nameAtt);
312
                    if ("schema_aware".Equals(featureName) || "Saxon-PE".Equals(featureName))   // TODO: test Saxon-PE properly
313
                    {
314
                        schemaAware = "on".Equals(feature.GetAttributeValue(behaviorAtt));
315
                    }
316
                    else if ("XML_1.1".Equals(featureName))
317
                    {
318
                        xml11 = "on".Equals(feature.GetAttributeValue(behaviorAtt));
319
                    }
320
                    else if ("backwards_compatibility".Equals(featureName))
321
                    {
322
                        backwardsCompatibility = "on".Equals(feature.GetAttributeValue(behaviorAtt));
323
                    }
324
                    else if ("disabling_output_escaping".Equals(featureName))
325
                    {
326
                        supportsDOE = "on".Equals(feature.GetAttributeValue(behaviorAtt));
327
                    }
328
                }
329
                IEnumerator choices = discretionaryItems.EnumerateAxis(
330
                        XdmAxis.Child, discretionaryChoiceNT);
331
                while (choices.MoveNext())
332
                {
333
                    XdmNode choice = (XdmNode)choices.Current;
334
                    String featureName = choice.GetAttributeValue(nameAtt);
335
                    if ("error".Equals(choice.GetAttributeValue(behaviorAtt)))
336
                    {
337
                        recoverRecoverable = false;
338
                    }
339
                    else if ("SESU0007".Equals(featureName))
340
                    {
341
                        recoverSESU0007 = "recovery".Equals(choice.GetAttributeValue(behaviorAtt));
342
                    }
343
                }
344
                IEnumerator versions = discretionaryItems.EnumerateAxis(
345
                        XdmAxis.Child, discretionaryVersionNT);
346
                while (versions.MoveNext())
347
                {
348
                    XdmNode dv = (XdmNode)versions.Current;
349
                    useXSLT30 = ("XSLT30" == dv.GetAttributeValue(specAtt));
350
                }
351
            }
352

    
353
            if (!backwardsCompatibility)
354
            {
355
                // Saxon cannot run with BC switched off
356
                results.WriteLine(" <testcase name='" + testName + "' result='not run' comment='requires backwards-compatibility=off'/>");
357
                continue;
358
            }
359

    
360
            if (!supportsDOE)
361
            {
362
                // Saxon cannot run with DOE switched off
363
                results.WriteLine(" <testcase name='" + testName + "' result='not run' comment='requires disable-output-escaping=off'/>");
364
                continue;
365
            }
366

    
367
            if (recoverSESU0007)
368
            {
369
                // Saxon cannot recover from error SESU0007
370
                results.WriteLine(" <testcase name='" + testName + "' result='not run' comment='requires recovery from error SESU0007'/>");
371
                continue;
372
            }
373

    
374
            XdmNode initialMode = getChildElement(testInput, initialModeNT);
375
            QName initialModeName = null;
376
            if (initialMode != null)
377
            {
378
                String ini = initialMode.GetAttributeValue(qnameAtt);
379
                initialModeName = makeQName(ini, initialMode);
380
            }
381

    
382
            XdmNode initialTemplate = getChildElement(testInput, entryNamedTemplateNT);
383
            QName initialTemplateName = null;
384
            if (initialTemplate != null)
385
            {
386
                String ini = initialTemplate.GetAttributeValue(qnameAtt);
387
                initialTemplateName = makeQName(ini, initialTemplate);
388
            }
389

    
390
            XdmNode initialContextNode = getChildElement(testInput, initialContextNodeNT);
391
            String initialContextPath = null;
392
            if (initialContextNode != null)
393
            {
394
                initialContextPath = initialContextNode.StringValue;
395
            }
396

    
397
            XdmNode validation = getChildElement(testInput, validationNT);
398
            String validationMode = null;
399
            if (validation != null)
400
            {
401
                validationMode = validation.GetAttributeValue(modeAtt);
402
            }
403

    
404
            Hashtable paramTable = null;
405
            XdmNode paramList = getChildElement(testInput, stylesheetParametersNT);
406
            if (paramList != null)
407
            {
408
                paramTable = new Hashtable(5);
409
                IEnumerator paramIter = paramList.EnumerateAxis(XdmAxis.Child, paramNT);
410
                while (paramIter.MoveNext())
411
                {
412
                    XdmNode param = (XdmNode)paramIter.Current;
413
                    QName name = makeQName(param.GetAttributeValue(qnameAtt), param);
414
                    String value = param.StringValue;
415
                    paramTable.Add(name, value);
416
                }
417
            }
418

    
419
            IEnumerator schemas = testInput.EnumerateAxis(XdmAxis.Child, schemaNT);
420
            while (schemas.MoveNext())
421
            {
422
                XdmNode schema = (XdmNode)schemas.Current;
423
                if (schema == null)
424
                {
425
                    break;
426
                }
427
                schemaAware = true;
428
                String role = schema.GetAttributeValue(roleAtt);
429
                if (("source-validator".Equals(role) || "source-reference".Equals(role))
430
                    /* && schema.GetAttributeValue(validatesAtt) != null */)
431
                {
432
                    validationMode = "strict";
433
                    // TODO: control which source documents are validated...
434
                }
435
            }
436
            XdmNode testOutput = getChildElement(testCase, outputNT);
437
            XdmNode resultDocument = getChildElement(testOutput, resultDocumentNT);
438
            // TODO: handle alternative result documents
439
            String refFileName = null;
440
            String outFileName;
441
            String comparator = "xml";
442
            if (resultDocument != null)
443
            {
444
                String relativePath = resultDocument.GetAttributeValue(fileAtt);
445
                int slash = relativePath.IndexOf('/');
446
                if (slash > 0)
447
                {
448
                    String relativeDir = relativePath.Substring(0, slash);
449
                    String fullDir = testSuiteDir + '/' + getResultDirectoryName() + "/" + relativeDir;
450
                    if (!Directory.Exists(fullDir))
451
                    {
452
                        Directory.CreateDirectory(fullDir);
453
                    }
454
                }
455
                refFileName = testSuiteDir + "/ExpectedTestResults/" + relativePath;
456
                outFileName = testSuiteDir + '/' + getResultDirectoryName() + "/" + relativePath;
457
                comparator = resultDocument.GetAttributeValue(typeAtt);
458
            }
459
            else
460
            {
461
                outFileName = testSuiteDir + '/' + getResultDirectoryName() + "/temp.out";
462
            }
463
            XdmNode error = getChildElement(testOutput, errorNT);
464
            String expectedError = null;
465
            if (error != null)
466
            {
467
                expectedError = error.GetAttributeValue(errorIdAtt);
468
            }
469
            bool success;
470
            Exception xsltOutcome =
471
                runXSLT(testName, absXMLName, absXSLName, initialModeName, initialTemplateName,
472
                    outFileName, paramTable, initialContextPath,
473
                    useAssociated, schemaAware, validationMode, recoverRecoverable, useXSLT30);
474
            if (xsltOutcome == null)
475
            {
476
                success = true;
477
                if (expectedError != null && resultDocument == null)
478
                {
479
                    log.WriteLine("Test failed. Expected error " + expectedError + ", got success");
480
                    feedback.Feedback(passed, failed++, total);
481
                    success = false;
482
                    results.WriteLine(" <testcase name='" + testName +
483
                            "' result='differ' comment='Expected error " +
484
                            expectedError + ", got success'/>");
485
                }
486
                else
487
                {
488
                    feedback.Feedback(passed++, failed, total);
489
                }
490
            }
491
            else
492
            {
493
                String errorCode = null;
494
                if (xsltOutcome is StaticError)
495
                {
496
                    errorCode = ((StaticError)xsltOutcome).ErrorCode.LocalName;
497
                }
498
                else if (xsltOutcome is DynamicError)
499
                {
500
                    errorCode = ((DynamicError)xsltOutcome).ErrorCode.LocalName;
501
                }
502
                if (expectedError != null && errorCode != null && errorCode.Equals(expectedError))
503
                {
504
                    feedback.Feedback(passed++, failed, total);
505
                    log.WriteLine("Test succeeded (" + expectedError + ')');
506
                    results.WriteLine(" <testcase name='" + testName +
507
                            "' result='full' comment='Error " +
508
                            expectedError + " as expected'/>");
509
                }
510
                else if (expectedError != null)
511
                {
512
                    feedback.Feedback(passed++, failed, total);
513
                    log.WriteLine("Test succeeded (??) (expected " + expectedError + ", got " + errorCode + ')');
514
                    results.WriteLine(" <testcase name='" + testName +
515
                            "' result='different-error' comment='Expected " +
516
                            expectedError + " got " + errorCode + "'/>");
517
                }
518
                else
519
                {
520
                    feedback.Feedback(passed, failed++, total);
521
                    log.WriteLine("Test failed. Expected success, got " + errorCode);
522
                    results.WriteLine(" <testcase name='" + testName +
523
                            "' result='differ' comment='Expected success, got " +
524
                            errorCode + "'/>");
525
                    results.WriteLine(" <!--" + xsltOutcome.Message + "-->");
526
                }
527
                success = false;
528
                continue;
529
            }
530

    
531

    
532
            if (success)
533
            {
534
                String outcome = fileComparer.compare(outFileName, refFileName, comparator);
535
                if (outcome == "OK")
536
                {
537
                    results.WriteLine(" <testcase name='" + testName + "' result='full'/>");
538
                }
539
                else if (outcome.StartsWith("#"))
540
                {
541
                    results.WriteLine(" <testcase name='" + testName + "' result='full' + comments='" + outcome.Substring(1) + "/>");
542
                }
543
                else
544
                {
545
                    results.WriteLine(" <testcase name='" + testName + "' result='differ' comments='" + outcome + "'/>");
546
                }
547
            }
548

    
549
        }
550

    
551
        results.WriteLine("</test-suite-result>");
552
        results.Close();
553
        log.Close();
554

    
555
        //} 
556
    }
557

    
558
    private static QName makeQName(String lexical, XdmNode element)
559
    {
560
        if (lexical.IndexOf(":") >= 0)
561
        {
562
            return new QName(lexical, element);
563
        }
564
        else
565
        {
566
            return new QName("", lexical);
567
        }
568
    }
569

    
570
    protected string getResultDirectoryName()
571
    {
572
        return "SaxonResults.Net";
573
    }
574

    
575
    protected bool isExcluded(String testName)
576
    {
577
        return false;
578
    }
579

    
580
    /// <summary>
581
    /// Run the transformation
582
    /// </summary>
583
    /// <param name="testName"></param>
584
    /// <param name="xml"></param>
585
    /// <param name="xsl"></param>
586
    /// <param name="initialMode"></param>
587
    /// <param name="initialTemplate"></param>
588
    /// <param name="outfile"></param>
589
    /// <param name="paramTable"></param>
590
    /// <param name="initialContextPath"></param>
591
    /// <param name="useAssociated"></param>
592
    /// <param name="schemaAware"></param>
593
    /// <param name="validationMode"></param>
594
    /// <param name="recoverRecoverable"></param>
595
    /// <returns>Either null, indicating success, or an Exception object with information about the failure</returns>
596

    
597
    protected Exception runXSLT(String testName, String xml, String xsl, QName initialMode,
598
                           QName initialTemplate, String outfile, Hashtable paramTable, String initialContextPath,
599
                           bool useAssociated, bool schemaAware,
600
                           String validationMode, bool recoverRecoverable, bool useXSLT30)
601
    {
602
        Serializer sr = processor.NewSerializer();
603
        sr.SetOutputFile(outfile);
604
        Processor f;
605
        if (noCacheTests.ContainsKey(testName)) {
606
            //create a custom Processor to avoid schema caching
607
            f = new Processor(true);
608
        }
609
        else if (schemaAware)
610
        {
611
            f = schemaAwareProcessor;
612
            if (f == null)
613
            {
614
                return new DynamicError("Saxon-SA not available");
615
            }
616
        }
617
        else if (xml11)
618
        {
619
            f = processor;
620
            // Use an Xml 1.1 processor
621
        }
622
        else
623
        {
624
            f = processor;
625
        }
626
        
627

    
628
        XdmNode source = null;
629

    
630
        IList <StaticError> errors = new List<StaticError>();
631
        XsltCompiler compiler = f.NewXsltCompiler();
632
        compiler.SchemaAware = schemaAware;
633
        compiler.ErrorList = errors;
634
        if (useXSLT30)
635
        {
636
            compiler.XsltLanguageVersion = "3.0";
637
        }
638
        XsltExecutable sheet = null;
639
        XsltTransformer inst;
640

    
641
        if (useAssociated)
642
        {
643
            try
644
            {
645
                source = buildSource(f.NewDocumentBuilder(), xml, validationMode);
646
            }
647
            catch (Exception e)
648
            {
649
                log.WriteLine("Failed to build source document: " + e.Message);
650
                return e;
651
            }
652
            try
653
            {
654
                sheet = compiler.CompileAssociatedStylesheet(source);
655
            }
656
            catch (Exception e)
657
            {
658
                log.WriteLine("Failed to compile stylesheet: " + e.Message);
659
                if (errors.Count > 0)
660
                {
661
                    return (Exception)errors[0];
662
                    //QName code = ((StaticError)errors[0]).ErrorCode;
663
                    //(code == null ? "Failed to compile stylesheet: " + e.Message : code.LocalName);
664
                }
665
                else
666
                {
667
                    return e;
668
                }
669
            }
670
        }
671
        else
672
        {
673
            Stream stream = new FileStream(xsl, FileMode.Open, FileAccess.Read);
674
            compiler.BaseUri = new Uri(xsl);
675
            try
676
            {
677
                sheet = compiler.Compile(stream);
678
            }
679
            catch (StaticError e)
680
            {
681
                if (errors.Count > 0)
682
                {
683
                    return ((StaticError)errors[0]);
684
                }
685
                else
686
                {
687
                    log.WriteLine(e.Message);
688
                    return e;
689
                }
690
            }
691
            catch (Exception e2)
692
            {
693
                log.WriteLine("Unexpected CRASH: " + e2.Message);
694
                log.WriteLine(e2.StackTrace);
695
                return e2;
696
            }
697
            finally
698
            {
699
                stream.Close();
700
            }
701
        }
702
        if (initialContextPath != null)
703
        {
704
            if (source == null && xml != null)
705
            {
706
                try
707
                {
708
                    source = buildSource(f.NewDocumentBuilder(), xml, validationMode);
709
                }
710
                catch (Exception e)
711
                {
712
                    log.WriteLine("Failed to build source document: " + e.Message);
713
                    return e;
714
                }
715
            }
716

    
717
            XPathCompiler xc = f.NewXPathCompiler();
718
            XPathExecutable exp = xc.Compile(initialContextPath);
719
            XPathSelector xpe = exp.Load();
720
            xpe.ContextItem = source;
721
            XdmNode node = (XdmNode)xpe.EvaluateSingle();
722
            source = node;
723

    
724
        }
725

    
726
        inst = sheet.Load();
727
        if (source != null) {
728
            inst.InitialContextNode = source;
729
        }
730

    
731
        if (source == null && xml != null)
732
        {
733
            Stream stream = new FileStream(xml, FileMode.Open, FileAccess.Read);
734
            inst.SetInputStream(stream, new Uri(xml));
735
        }
736

    
737
        
738
        if (initialMode != null)
739
        {
740
            inst.InitialMode = initialMode;
741
        }
742
        if (initialTemplate != null)
743
        {
744
            try
745
            {
746
                inst.InitialTemplate = initialTemplate;
747
            }
748
            catch (DynamicError e)
749
            {
750
                return e;
751
            }
752
        }
753
        if (paramTable != null)
754
        {
755
            foreach (DictionaryEntry de in paramTable)
756
            {
757
                inst.SetParameter((QName)de.Key, new XdmAtomicValue(de.Value.ToString()));
758
            }
759
        }
760
        
761
        inst.BaseOutputUri = new Uri(outfile);
762
        //inst.RecoveryPolicy = recoverRecoverable ? RecoveryPolicy.RecoverSilently : RecoveryPolicy.DoNotRecover;
763

    
764
        if ("strict" == validationMode)
765
        {
766
            inst.SchemaValidationMode = SchemaValidationMode.Strict;
767
        }
768
        else
769
        {
770
            inst.SchemaValidationMode = SchemaValidationMode.None;
771
        }
772

    
773
        //inst.setURIResolver(factory.getURIResolver());
774
        //inst.setErrorListener(errorListener);
775
        //((Controller)inst).setRecoveryPolicy(recoverRecoverable ? Configuration.RECOVER_SILENTLY : Configuration.DO_NOT_RECOVER);
776
        // To avoid test results being dependent on the date and time (and timezone), set a fixed
777
        // date and time for the run
778
        //((Controller)inst).setCurrentDateTime(new DateTimeValue("2005-01-01T12:49:30.5+01:00"));
779

    
780
        try
781
        {
782
            inst.Run(sr);
783
        }
784
        catch (DynamicError e)
785
        {
786
            log.WriteLine(e.Message);
787
            return e;
788
        }
789
        catch (Exception e2)
790
        {
791
            log.WriteLine("Unexpected CRASH: " + e2.Message);
792
            log.WriteLine(e2.StackTrace);
793
            return e2;
794
        }
795
        return null;    // indicating success
796
    }
797

    
798
    /**
799
     * Construct source object. This method allows subclassing e.g. to build a DOM or XOM source.
800
     * @param xml
801
     * @return
802
     * @throws XPathException
803
     */
804

    
805
    protected XdmNode buildSource(DocumentBuilder builder, String xml, String validationMode)
806
    {
807
        if ("strict".Equals(validationMode))
808
        {
809
            builder.SchemaValidationMode = SchemaValidationMode.Strict;
810
        }
811
        else
812
        {
813
            builder.SchemaValidationMode = SchemaValidationMode.None;
814
        }
815
        return builder.Build(new Uri(xml));
816
    }
817

    
818

    
819
    private void outputDiscretionaryItems()
820
    {
821
        results.WriteLine("  <discretionary-items/>");
822
    }
823

    
824

    
825

    
826

    
827
}
828

    
829

    
(19-19/19)