예제 #1
0
        public static void validation()
        {
            Saxon.Api.Processor proc = new Processor(true);

            SchemaManager schemaManager = proc.SchemaManager;

            FileStream xsdFs         = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "Validation\\SAFTPT1.04_01.xsd", FileMode.Open);
            XmlReader  validationXml = XmlReader.Create(xsdFs);

            Boolean bSchema = schemaManager == null;
            Boolean bXml    = validationXml == null;

            //throw new Exception("debug: schema: " + bSchema + " xml: " + bXml);

            // XmlReaderSettings settings = new XmlReaderSettings();
            // settings.ValidationType = ValidationType.Schema;

            schemaManager.Compile(validationXml);
            SchemaValidator schemaValidator = schemaManager.NewSchemaValidator();

            FileStream xmlFs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "Assets\\SAFT_DEMOSINF_01-01-2016_31-12-2016.xml", FileMode.Open);

            schemaValidator.SetSource(XmlReader.Create(xmlFs));

            schemaValidator.Run();
        }
예제 #2
0
        private static bool LoadSchemaDocuments(XPathCompiler xpc, XdmItem env, SchemaManager manager)
        {
            bool           validateSources = false;
            XmlUrlResolver res             = new XmlUrlResolver();

            foreach (XdmItem schema in xpc.Evaluate("schema", env))
            {
                String role       = ((XdmNode)schema).GetAttributeValue(new QName("role"));
                String xsdVersion = ((XdmNode)schema).GetAttributeValue(new QName("xsd-version"));
                if (xsdVersion != null)
                {
                    manager.XsdVersion = xsdVersion;
                }
                if (!"secondary".Equals(role))
                {
                    String     href = ((XdmNode)schema).GetAttributeValue(new QName("file"));
                    Uri        uri  = res.ResolveUri(((XdmNode)env).BaseUri, href);
                    FileStream file = new FileStream(uri.AbsolutePath, FileMode.Open, FileAccess.Read);
                    try
                    {
                        manager.Compile(file, uri);
                    }
                    catch (Exception err)
                    {
                        System.Console.WriteLine("*** Failed to load schema: " + err.Message + ", Trace:" + err.StackTrace);
                    }

                    if ("source-reference".Equals(role))
                    {
                        validateSources = true;
                    }
                }
            }
            return(validateSources);
        }
예제 #3
0
        public override void LoadSchema(Uri schemaUri)
        {
            SchemaManager manager = processor.SchemaManager;

            manager.Compile(schemaUri);
            documentBuilder = processor.NewDocumentBuilder();
            documentBuilder.SchemaValidationMode = SchemaValidationMode.Strict;
            schemaAware = true;
        }
        public bool Validate(string xml)
        {
            bool result = true;

            Saxon.Api.Processor proc          = new Processor(true);
            SchemaManager       schemaManager = proc.SchemaManager;

            schemaManager.Compile(XmlReader.Create(new StringReader(this.xsd)));
            SchemaValidator validator = schemaManager.NewSchemaValidator();

            validator.SetSource(XmlReader.Create(new StringReader(xml)));
            validator.ErrorList = new ArrayList();
            try
            {
                validator.Run();
            }
            catch (Exception)
            {
                result = false;
            }
            return(result);
        }
예제 #5
0
    public void go(String[] args)
    {
        Console.WriteLine("Testing Saxon " + processor.ProductVersion);
        testSuiteDir = args[0];
        if (testSuiteDir.EndsWith("/"))
        {
            testSuiteDir = testSuiteDir.Substring(0, testSuiteDir.Length - 1);
        }
        saxonResultsDir = args[1];
        if (saxonResultsDir.EndsWith("/"))
        {
            saxonResultsDir = saxonResultsDir.Substring(0, testSuiteDir.Length - 1);
        }
        Hashtable exceptions = new Hashtable();

        if (args.Length > 1)
        {
            testPattern = (args[2]); // TODO: allow a regex
        }

        for (int i = 0; i < args.Length; i++)
        {
            if (args[i].Equals("-w"))
            {
                //showWarnings = true;
            }
            else if (args[i].Equals("-debug"))
            {
                debug = true;
            }
        }

        fileComparer = new FileComparer(processor, testSuiteDir);

        XPathCompiler xpc = processor.NewXPathCompiler();

        xpc.DeclareNamespace("t", testURI);
        xpc.DeclareVariable(new QName("", "param"));
        findSourcePath = xpc.Compile("//t:test-suite/t:sources/t:source[@ID=$param]");

        findCollection = xpc.Compile("//t:test-suite/t:sources/t:collection[@ID=$param]");

        xpc = processor.NewXPathCompiler();
        xpc.DeclareNamespace("t", testURI);
        xpc.DeclareVariable(new QName("", "testcase"));
        xpc.DeclareVariable(new QName("", "moduleuri"));
        findModule = xpc.Compile("for $m in $testcase/t:module[@namespace=$moduleuri] " +
                                 "return concat('file:///" + testSuiteDir +
                                 "/', root($testcase)/t:test-suite/t:sources/t:module[@ID=string($m)]/@FileName, '.xq')");

        //xpc = processor.NewXPathCompiler();
        //xpc.DeclareNamespace("saxon", "http://saxon.sf.net/");
        //xpc.DeclareVariable(new QName("", "actual"));
        //xpc.DeclareVariable(new QName("", "gold"));
        //xpc.DeclareVariable(new QName("", "debug"));
        //compareDocuments = xpc.Compile("saxon:deep-equal($actual, $gold, (), if ($debug) then 'JNCPS?!' else 'JNCPS')");

        QName testCaseNT             = new QName(testURI, "test-case");
        QName nameNT                 = new QName(testURI, "name");
        QName queryNT                = new QName(testURI, "query");
        QName inputNT                = new QName(testURI, "input");
        QName inputFileNT            = new QName(testURI, "input-file");
        QName inputUriNT             = new QName(testURI, "input-URI");
        QName defaultCollectionNT    = new QName(testURI, "defaultCollection");
        QName outputFileNT           = new QName(testURI, "output-file");
        QName expectedErrorNT        = new QName(testURI, "expected-error");
        QName schemaNT               = new QName(testURI, "schema");
        QName contextItemNT          = new QName(testURI, "contextItem");
        QName inputQueryNT           = new QName(testURI, "input-query");
        QName sourceDocumentNT       = new QName(testURI, "source-document");
        QName errorNT                = new QName(testURI, "error");
        QName validationNT           = new QName(testURI, "validation");
        QName discretionaryItemsNT   = new QName(testURI, "discretionary-items");
        QName discretionaryFeatureNT = new QName(testURI, "discretionary-feature");
        QName discretionaryChoiceNT  = new QName(testURI, "discretionary-choice");
        QName initialContextNodeNT   = new QName(testURI, "initial-context-node");


        QName fileAtt      = new QName("", "file");
        QName filePathAtt  = new QName("", "FilePath");
        QName fileNameAtt  = new QName("", "FileName");
        QName errorIdAtt   = new QName("", "error-id");
        QName compareAtt   = new QName("", "compare");
        QName nameAtt      = new QName("", "name");
        QName behaviorAtt  = new QName("", "behavior");
        QName qnameAtt     = new QName("", "qname");
        QName modeAtt      = new QName("", "mode");
        QName validatesAtt = new QName("", "validates");
        QName variableAtt  = new QName("", "variable");
        QName roleAtt      = new QName("", "role");

        DocumentBuilder builder       = processor.NewDocumentBuilder();
        XdmNode         exceptionsDoc = builder.Build(new Uri(saxonResultsDir + "/exceptions.xml"));

        // The exceptions.xml file contains details of tests that aren't to be run, for example
        // because they have known bugs or require special configuration

        IEnumerator exceptionTestCases = exceptionsDoc.EnumerateAxis(XdmAxis.Descendant, new QName("", "exception"));

        while (exceptionTestCases.MoveNext())
        {
            XdmNode  n          = (XdmNode)exceptionTestCases.Current;
            String   nameAttVal = n.StringValue;
            char[]   seps       = { ' ', '\n', '\t' };
            String[] parts      = nameAttVal.Split(seps);
            foreach (string p in parts)
            {
                if (!exceptions.ContainsKey(p))
                {
                    exceptions.Add(p, "Exception");
                }
            }
        }

        // Hash table containing all source documents. The key is the document name in the
        // catalog, the value is the corresponding document node

        Hashtable sourceDocs = new Hashtable(50);

        // Load the catalog

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

        // Add all Static Typing test cases to the exceptions list

        xpc = processor.NewXPathCompiler();
        xpc.DeclareNamespace("t", testURI);
        XPathSelector st = xpc.Compile("//t:test-group[@name='StaticTyping']//t:test-case").Load();

        st.ContextItem = catalog;
        IEnumerator ste = st.GetEnumerator();

        while (ste.MoveNext())
        {
            XdmNode testCase = (XdmNode)ste.Current;
            exceptions.Add(testCase.GetAttributeValue(nameAtt), "StaticTypingException");
        }

        // Create the results file

        results = new StreamWriter(saxonResultsDir + "/results"
                                   + processor.ProductVersion + "n.xml");

        results.WriteLine("<test-suite-result xmlns='http://www.w3.org/2005/02/query-test-XQTSResult'>");

        // Pre-load all the schemas

        SchemaManager mgr = processor.SchemaManager;
        IEnumerator   se  = catalog.EnumerateAxis(XdmAxis.Descendant, schemaNT);

        while (se.MoveNext())
        {
            XdmNode schemaNode = (XdmNode)se.Current;
            Console.WriteLine("Loading schema " + schemaNode.GetAttributeValue(fileNameAtt));
            Uri location = new Uri(testSuiteDir + "/" + schemaNode.GetAttributeValue(fileNameAtt));
            mgr.Compile(location);
        }

        total = 0;
        IEnumerator testCases = catalog.EnumerateAxis(XdmAxis.Descendant, testCaseNT);

        while (testCases.MoveNext())
        {
            total++;
        }

        // Process the test cases in turn

        testCases = catalog.EnumerateAxis(XdmAxis.Descendant, testCaseNT);
        while (testCases.MoveNext())
        {
            XdmNode testCase = (XdmNode)testCases.Current;

            String testName = testCase.GetAttributeValue(nameAtt);
            if (testPattern != null && !testName.StartsWith(testPattern))
            {
                continue;
            }
            if (exceptions.ContainsKey(testName))
            {
                continue;
            }

            Console.WriteLine("Test " + testName);


            // Compile the query

            String errorCode = null;

            String  filePath  = testCase.GetAttributeValue(filePathAtt);
            XdmNode query     = getChildElement(testCase, queryNT);
            String  queryName = query.GetAttributeValue(nameAtt);
            String  queryPath = testSuiteDir + "/Queries/XQuery/" + filePath + queryName + ".xq";

            XQueryCompiler compiler = processor.NewXQueryCompiler();
            compiler.BaseUri       = new Uri(queryPath).ToString();
            compiler.QueryResolver = new XqtsModuleResolver(testCase, findModule);

            ArrayList errors = new ArrayList();
            compiler.ErrorList = errors;
            XQueryEvaluator xqe    = null;
            FileStream      stream = null;
            try
            {
                stream = new FileStream(queryPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                xqe    = compiler.Compile(stream).Load();
            }
            catch (Exception e)
            {
                if (errors.Count > 0 && ((StaticError)errors[0]).ErrorCode != null)
                {
                    errorCode = ((StaticError)errors[0]).ErrorCode.LocalName;
                }
                else if (e is StaticError && ((StaticError)e).ErrorCode != null)
                {
                    Console.WriteLine(e.Message);
                    errorCode = ((StaticError)e).ErrorCode.LocalName;
                }
                else
                {
                    Console.WriteLine(e.Message);
                    errorCode = "ErrorXXX";
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            // if the query compiled successfully, try to run it

            String outputPath = null;
            if (errorCode == null && xqe != null)
            {
                // Supply any input documents

                IEnumerator en = testCase.EnumerateAxis(XdmAxis.Child, inputFileNT);
                while (en.MoveNext())
                {
                    XdmNode file = (XdmNode)en.Current;
                    String  var  = file.GetAttributeValue(variableAtt);
                    if (var != null)
                    {
                        String  sourceName = file.StringValue;
                        XdmNode sourceDoc;
                        if (sourceDocs.ContainsKey(sourceName))
                        {
                            sourceDoc = (XdmNode)sourceDocs[sourceName];
                        }
                        else
                        {
                            sourceDoc = buildSource(catalog, builder, sourceName);
                            sourceDocs.Add(sourceName, sourceDoc);
                        }
                        xqe.SetExternalVariable(new QName("", var), sourceDoc);
                    }
                }

                // Supply any input URIs

                IEnumerator eu = testCase.EnumerateAxis(XdmAxis.Child, inputUriNT);
                while (eu.MoveNext())
                {
                    XdmNode file = (XdmNode)eu.Current;
                    String  var  = file.GetAttributeValue(variableAtt);
                    if (var != null)
                    {
                        String sourceName = file.StringValue;
                        if (sourceName.StartsWith("collection"))
                        {
                            // Supply a collection URI.
                            // This seems to be the only way to distinguish a document URI
                            // from a collection URI.
                            String        uri = "collection:" + sourceName;
                            XPathSelector xpe = findCollection.Load();
                            xpe.SetVariable(new QName("", "param"), new XdmAtomicValue(sourceName));
                            xpe.ContextItem = catalog;
                            XdmNode collectionNode = (XdmNode)xpe.EvaluateSingle();
                            if (collectionNode == null)
                            {
                                Console.WriteLine("*** Collection " + sourceName + " not found");
                            }
                            processor.RegisterCollection(new Uri(uri), getCollection(collectionNode));
                            xqe.SetExternalVariable(new QName("", var), new XdmAtomicValue(uri));
                        }
                        else
                        {
                            // Supply a document URI.
                            // We exploit the fact that the short name of the document is
                            // always the same as the file name in these tests
                            String uri = "file:///" + testSuiteDir + "/TestSources/" + sourceName + ".xml";
                            xqe.SetExternalVariable(new QName("", var), new XdmAtomicValue(uri));
                        }
                    }
                }

                // Supply the default collection if required

                XdmNode defaultCollection = getChildElement(testCase, defaultCollectionNT);
                if (defaultCollection != null)
                {
                    String        sourceName = defaultCollection.StringValue;
                    XPathSelector xpe        = findCollection.Load();
                    xpe.SetVariable(new QName("", "param"), new XdmAtomicValue(sourceName));
                    xpe.ContextItem = catalog;
                    XdmNode collectionNode = (XdmNode)xpe.EvaluateSingle();
                    if (collectionNode == null)
                    {
                        Console.WriteLine("*** Collection " + sourceName + " not found");
                    }
                    processor.RegisterCollection(null, getCollection(collectionNode));
                }

                // Supply any external variables defined as the result of a separate query

                IEnumerator ev = testCase.EnumerateAxis(XdmAxis.Child, inputQueryNT);
                while (ev.MoveNext())
                {
                    XdmNode inputQuery = (XdmNode)ev.Current;

                    String         fileName     = inputQuery.GetAttributeValue(nameAtt);
                    String         subQueryPath = testSuiteDir + "/Queries/XQuery/" + filePath + fileName + ".xq";
                    XQueryCompiler subCompiler  = processor.NewXQueryCompiler();
                    compiler.BaseUri = new Uri(subQueryPath).ToString();
                    FileStream subStream = new FileStream(subQueryPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    XdmValue   value     = subCompiler.Compile(subStream).Load().Evaluate();
                    String     var       = inputQuery.GetAttributeValue(variableAtt);
                    xqe.SetExternalVariable(new QName("", var), value);
                }

                // Supply the context item if required

                IEnumerator ci = testCase.EnumerateAxis(XdmAxis.Child, contextItemNT);
                while (ci.MoveNext())
                {
                    XdmNode file = (XdmNode)ci.Current;

                    String sourceName = file.StringValue;
                    if (!sourceDocs.ContainsKey(sourceName))
                    {
                        XdmNode doc = buildSource(catalog, builder, sourceName);
                        sourceDocs.Add(sourceName, doc);
                    }
                    XdmNode sourceDoc = (XdmNode)sourceDocs[sourceName];
                    xqe.ContextItem = sourceDoc;
                }

                // Create a serializer for the output


                outputPath = saxonResultsDir + "/results.net/" + filePath + queryName + ".out";
                Serializer sr = new Serializer();
                try
                {
                    sr.SetOutputFile(outputPath);
                    sr.SetOutputProperty(new QName("", "method"), "xml");
                    sr.SetOutputProperty(new QName("", "omit-xml-declaration"), "yes");
                    sr.SetOutputProperty(new QName("", "indent"), "no");
                }
                catch (DynamicError)
                {
                    // probably means that no output directory exists, which is probably because
                    // an error is expected
                    outputPath = saxonResultsDir + "/results.net/" + queryName + ".out";
                    sr.SetOutputFile(outputPath);
                }

                // Finally, run the query

                try
                {
                    xqe.Run(sr);
                }
                catch (DynamicError e)
                {
                    Console.WriteLine(e.Message);
                    QName code = e.ErrorCode;
                    if (code != null && code.LocalName != null)
                    {
                        errorCode = code.LocalName;
                    }
                    else
                    {
                        errorCode = "ErrYYYYY";
                    }
                }
                catch (Exception e2)
                {
                    Console.WriteLine("Unexpected exception: " + e2.Message);
                    Console.WriteLine(e2.StackTrace);
                    errorCode = "CRASH!!!";
                }
            }

            // Compare actual results with expected results

            if (errorCode != null)
            {
                // query returned an error at compile time or run-time, check this was expected

                string      expectedError = "";
                bool        matched       = false;
                IEnumerator en            = testCase.EnumerateAxis(XdmAxis.Child, expectedErrorNT);
                while (en.MoveNext())
                {
                    XdmNode error             = (XdmNode)en.Current;
                    String  expectedErrorCode = error.StringValue;
                    expectedError += (expectedErrorCode + " ");
                    if (expectedErrorCode.Equals(errorCode))
                    {
                        matched = true;
                        feedback.Feedback(passed++, failed, total);
                        Console.WriteLine("Error " + errorCode + " as expected");
                        results.WriteLine("<test-case name='" + testName + "' result='pass'/>");
                        break;
                    }
                }
                if (!matched)
                {
                    if (expectedError.Equals(""))
                    {
                        feedback.Feedback(passed, failed++, total);
                        Console.WriteLine("Error " + errorCode + ", expected success");
                        results.WriteLine("<test-case name='" + testName + "' result='fail' comment='error " + errorCode + ", expected success'/>");
                    }
                    else
                    {
                        feedback.Feedback(passed++, failed, total);
                        Console.WriteLine("Error " + errorCode + ", expected " + expectedError);
                        results.WriteLine("<test-case name='" + testName + "' result='pass' comment='error " + errorCode + ", expected " + expectedError + "'/>");
                    }
                }
            }
            else
            {
                // query returned no error

                bool        matched = false;
                String      diag    = "";
                IEnumerator en      = testCase.EnumerateAxis(XdmAxis.Child, outputFileNT);
                while (en.MoveNext())
                {
                    XdmNode outputFile = (XdmNode)en.Current;
                    String  fileName   = testSuiteDir + "/ExpectedTestResults/" + filePath + outputFile.StringValue;
                    String  comparator = outputFile.GetAttributeValue(compareAtt);
                    if (comparator.Equals("Inspect"))
                    {
                        matched = true;
                        feedback.Feedback(passed++, failed, total);
                        results.WriteLine("<test-case name='" + testName + "' result='inspect'/>");
                        break;
                    }
                    else
                    {
                        String comparison = fileComparer.compare(outputPath, fileName, comparator);
                        matched = (comparison == "OK" || comparison.StartsWith("#"));
                        if (matched)
                        {
                            feedback.Feedback(passed++, failed, total);
                            results.WriteLine("<test-case name='" + testName + "' result='pass'/>");
                            diag = diag + ("<!-- " + comparison + " -->\n");
                            break;
                        }
                    }
                }

                if (!matched)
                {
                    string      expectedError = "";
                    IEnumerator ee            = testCase.EnumerateAxis(XdmAxis.Child, expectedErrorNT);
                    while (ee.MoveNext())
                    {
                        XdmNode error             = (XdmNode)ee.Current;
                        String  expectedErrorCode = error.StringValue;
                        expectedError += (expectedErrorCode + " ");
                    }

                    if (expectedError.Equals(""))
                    {
                        feedback.Feedback(passed, failed++, total);
                        Console.WriteLine("Results differ from expected results");
                        results.WriteLine("<test-case name='" + testName + "' result='fail'/>");
                    }
                    else
                    {
                        feedback.Feedback(passed, failed++, total);
                        Console.WriteLine("Error " + expectedError + "expected but not reported");
                        results.WriteLine("<test-case name='" + testName + "' result='fail' comment='expected error " + expectedError + "not reported'/>");
                    }
                }
            }
        }

        results.WriteLine("</test-suite-result>");
        results.Close();
    }
예제 #6
0
    /**
     * Method main. First argument is the Saxon samples directory.
     */
    public static void Main(String[] argv)
    {
        String samplesDir;

        if (argv.Length > 0)
        {
            samplesDir = argv[0];
        }
        else
        {
            String home = Environment.GetEnvironmentVariable("SAXON_HOME");
            if (home == null)
            {
                Console.WriteLine("No input directory supplied, and SAXON_HOME is not set");
                return;
            }
            else
            {
                if (home.EndsWith("/") || home.EndsWith("\\"))
                {
                    samplesDir = home + "samples/";
                }
                else
                {
                    samplesDir = home + "/samples/";
                }
            }
        }

        UriBuilder ub = new UriBuilder();

        ub.Scheme = "file";
        ub.Host   = "";
        ub.Path   = samplesDir;
        Uri baseUri = ub.Uri;

        Console.WriteLine("Base URI: " + baseUri.ToString());

        // Create a schema-aware Processor

        Processor saxon = new Processor(true);

        // Load a schema

        SchemaManager manager = saxon.SchemaManager;

        manager.ErrorList = new ArrayList();
        Uri schemaUri = new Uri(baseUri, "data/books.xsd");

        try {
            manager.Compile(schemaUri);
        } catch (Exception e) {
            Console.WriteLine("Schema compilation failed with " + manager.ErrorList.Count + " errors");
            foreach (StaticError error in manager.ErrorList)
            {
                Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
            }
            return;
        }


        // Use this to validate an instance document

        SchemaValidator validator   = manager.NewSchemaValidator();
        Uri             instanceUri = new Uri(baseUri, "data/books.xml");

        validator.SetSource(instanceUri);
        validator.ErrorList = new ArrayList();
        XdmDestination psvi = new XdmDestination();

        validator.SetDestination(psvi);

        try {
            validator.Run();
        } catch (Exception e) {
            Console.WriteLine("Instance validation failed with " + validator.ErrorList.Count + " errors");
            foreach (StaticError error in validator.ErrorList)
            {
                Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
            }
        }


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

        XQueryCompiler  xq = saxon.NewXQueryCompiler();
        XQueryEvaluator xv = xq.Compile("data((//PRICE)[1]) instance of xs:decimal").Load();

        xv.ContextItem = psvi.XdmNode;
        Console.WriteLine("Price is decimal? " + xv.EvaluateSingle().ToString());
    }
예제 #7
0
        /**
         * Run the tests
         * @param args command line arguments
         * @throws SAXException
         * @throws ParserConfigurationException
         * @throws XPathException
         * @throws IOException
         * @throws URISyntaxException
         */

        public void go(String[] args)
        {
            if (args.Length == 0 || args[0] == "-?")
            {
                Console.WriteLine("SchemaTestSuiteDriver testDir [-w] [-onwards] -c:contributor? -s:setName? -g:groupName?");
            }
            Processor processor = new Processor(true);

            Console.WriteLine("Testing Saxon " + processor.ProductVersion);

            testSuiteDir = args[0];
            if (testSuiteDir.EndsWith("/"))
            {
                testSuiteDir = testSuiteDir.Substring(0, testSuiteDir.Length - 1);
            }
            String    testSetPattern   = null;  // TODO use a regex
            String    testGroupPattern = null;
            String    contributor      = null;
            Hashtable exceptions       = new Hashtable();

            for (int i = 1; i < args.Length; i++)
            {
                if (args[i] == ("-w"))
                {
                    //showWarnings = true;
                }
                else if (args[i] == ("-onwards"))
                {
                    onwards = true;
                }
                else if (args[i].StartsWith("-c:"))
                {
                    contributor = args[i].Substring(3);
                }
                else if (args[i].StartsWith("-s:"))
                {
                    testSetPattern = args[i].Substring(3);
                }
                else if (args[i].StartsWith("-g:"))
                {
                    testGroupPattern = args[i].Substring(3);
                }
                else if (args[i] == "-?")
                {
                    Console.WriteLine("Usage: SchemaTestSuiteDriver testDir [-w] [-s:testSetPattern] [-g:testGroupPattern]");
                }
            }

            int total  = 39700;
            int passed = 0;
            int failed = 0;

            try {
                xlinkHref = new QName("xlink", "http://www.w3.org/1999/xlink", "href");

                QName testCaseNT = new QName("", "", "testcase");
                QName commentNT  = new QName("", "", "comment");

                QName testSetRefNT       = new QName(testNS, "testSetRef");
                QName testGroupNT        = new QName(testNS, "testGroup");
                QName testSetNT          = new QName(testNS, "testSet");
                QName schemaTestNT       = new QName(testNS, "schemaTest");
                QName instanceTestNT     = new QName(testNS, "instanceTest");
                QName schemaDocumentNT   = new QName(testNS, "schemaDocument");
                QName instanceDocumentNT = new QName(testNS, "instanceDocument");
                QName expectedNT         = new QName(testNS, "expected");
                QName currentNT          = new QName(testNS, "current");

                QName validityAtt        = new QName("", "", "validity");
                QName nameAtt            = new QName("", "", "name");
                QName contributorAtt     = new QName("", "", "contributor");
                QName setAtt             = new QName("", "", "set");
                QName groupAtt           = new QName("", "", "group");
                QName statusAtt          = new QName("", "", "status");
                QName bugzillaAtt        = new QName("", "", "bugzilla");
                QName targetNamespaceAtt = new QName("", "", "targetNamespace");
                QName schemaVersion      = new QName("saxon", "http://saxon.sf.net/", "schemaVersion");


                DocumentBuilder builder = processor.NewDocumentBuilder();
                builder.BaseUri = new Uri(testSuiteDir + "/");
                XdmNode catalog = builder.Build(
                    new FileStream(testSuiteDir + "/suite.xml", FileMode.Open, FileAccess.Read, FileShare.Read));

                results = new StreamWriter(testSuiteDir + "/saxon/SaxonResults"
                                           + processor.ProductVersion + "n.xml");

                results.Write("<testSuiteResults xmlns='" + testNS + "' xmlns:saxon='http://saxon.sf.net/' " +
                              "suite='TS_2006' " +
                              "processor='Saxon-SA (Java) 8.8++' submitDate='2007-01-05' publicationPermission='public'>\n");

                XdmNode exceptionsDoc = builder.Build(
                    new FileStream(testSuiteDir + "/saxon/exceptions.xml",
                                   FileMode.Open, FileAccess.Read, FileShare.Read));


                IEnumerator exceptionTestCases = exceptionsDoc.EnumerateAxis(XdmAxis.Descendant, new QName("", "testcase"));
                while (exceptionTestCases.MoveNext())
                {
                    XdmNode testCase = (XdmNode)exceptionTestCases.Current;
                    String  set      = testCase.GetAttributeValue(setAtt);
                    String  group    = testCase.GetAttributeValue(groupAtt);
                    String  comment  = getChildElement(testCase, commentNT).StringValue;
                    exceptions[set + "#" + group] = comment;
                }

                IEnumerator testSets = catalog.EnumerateAxis(XdmAxis.Descendant, testSetRefNT);
                while (testSets.MoveNext())
                {
                    XdmNode testSetRef     = (XdmNode)testSets.Current;
                    XdmNode testSetDoc     = getLinkedDocument(testSetRef, processor, false);
                    XdmNode testSetElement = getChildElement(testSetDoc, testSetNT);

                    if (testSetElement == null)
                    {
                        feedback.Message("test set doc has no TestSet child: " + testSetDoc.BaseUri, true);
                        continue;
                    }

                    String testSetName = testSetElement.GetAttributeValue(nameAtt);
                    if (testSetPattern != null && !testSetName.StartsWith(testSetPattern))
                    {
                        continue;
                    }
                    if (contributor != null && contributor != testSetElement.GetAttributeValue(contributorAtt))
                    {
                        continue;
                    }

                    bool needs11 = (testSetElement.GetAttributeValue(schemaVersion) == "1.1");

                    IEnumerator testGroups = testSetElement.EnumerateAxis(XdmAxis.Child, testGroupNT);
                    while (testGroups.MoveNext())
                    {
                        XdmNode testGroup = (XdmNode)testGroups.Current;

                        String testGroupName = testGroup.GetAttributeValue(nameAtt);
                        String exception     = (String)exceptions[testSetName + "#" + testGroupName];

                        if (testGroupPattern != null && !testGroupName.StartsWith(testGroupPattern))
                        {
                            continue;
                        }
                        Console.WriteLine("TEST SET " + testSetName + " GROUP " + testGroupName, false);
                        if (onwards)
                        {
                            testGroupPattern = null;
                            testSetPattern   = null;
                        }
                        Processor testConfig = new Processor(true);
                        if (needs11)
                        {
                            testConfig.SetProperty("http://saxon.sf.net/feature/xsd-version", "1.1");
                        }
                        SchemaManager schemaManager = testConfig.SchemaManager;


                        //testConfig.setHostLanguage(Configuration.XML_SCHEMA);
                        testConfig.SetProperty("http://saxon.sf.net/feature/validation-warnings", "true");
                        IEnumerator schemaTests   = testGroup.EnumerateAxis(XdmAxis.Child, schemaTestNT);
                        bool        schemaQueried = false;
                        String      bugzillaRef   = null;

                        while (schemaTests.MoveNext())
                        {
                            XdmNode schemaTest = (XdmNode)schemaTests.Current;
                            if (schemaTest == null)
                            {
                                break;
                            }
                            bugzillaRef = null;
                            String testName = schemaTest.GetAttributeValue(nameAtt);
                            if (exception != null)
                            {
                                results.Write("<testResult set='" + testSetName +
                                              "' group='" + testGroupName +
                                              "' test='" + testName +
                                              "' validity='notKnown' saxon:outcome='notRun' saxon:comment='" + exception +
                                              "'/>\n");
                                continue;
                            }
                            bool    queried       = false;
                            XdmNode statusElement = getChildElement(schemaTest, currentNT);
                            if (statusElement != null)
                            {
                                String status = statusElement.GetAttributeValue(statusAtt);
                                queried     = ("queried" == status);
                                bugzillaRef = statusElement.GetAttributeValue(bugzillaAtt);
                            }
                            if (queried)
                            {
                                schemaQueried = true;
                            }
                            Console.WriteLine("TEST SCHEMA " + testName + (queried ? " (queried)" : ""));
                            bool        success  = true;
                            IEnumerator schemata = schemaTest.EnumerateAxis(XdmAxis.Child, schemaDocumentNT);
                            while (schemata.MoveNext())
                            {
                                XdmNode schemaDocumentRef = (XdmNode)schemata.Current;
                                if (schemaDocumentRef == null)
                                {
                                    break;
                                }
                                Console.WriteLine("Loading schema at " + schemaDocumentRef.GetAttributeValue(xlinkHref));
                                XdmNode     schemaDoc     = getLinkedDocument(schemaDocumentRef, testConfig, false);
                                IEnumerator schemaDocKids = schemaDoc.EnumerateAxis(XdmAxis.Child);
                                XdmNode     schemaElement = null;
                                while (schemaDocKids.MoveNext())
                                {
                                    schemaElement = (XdmNode)schemaDocKids.Current;
                                    if (schemaElement.NodeKind == XmlNodeType.Element)
                                    {
                                        break;
                                    }
                                }
                                String targetNamespace = schemaElement.GetAttributeValue(targetNamespaceAtt);
                                //if (targetNamespace != null && schemaManager. isSchemaAvailable(targetNamespace)) {
                                // do nothing
                                // TODO: this is the only way I can get MS additional test addB132 to work.
                                // It's not ideal: addSchemaSource() ought to be a no-op if the schema components
                                // are already loaded, but in fact recompiling the imported schema document on its
                                // own is losing the substitution group membership that was defined in the
                                // importing document.
                                //} else {
                                IList <StaticError> errorList = new List <StaticError>();
                                schemaManager.ErrorList = errorList;
                                try
                                {
                                    schemaManager.Compile(schemaDoc);
                                }
                                catch (Exception e)
                                {
                                    if (errorList.Count == 0)
                                    {
                                        feedback.Message("In " + testName + ", exception thrown but no errors in ErrorList\n", true);
                                        results.Write("<!--" + e.Message + "-->");
                                        success = false;
                                    }
                                }
                                for (int i = 0; i < errorList.Count; i++)
                                {
                                    if (errorList[i] is StaticError)
                                    {
                                        StaticError err = (StaticError)errorList[i];
                                        if (!err.IsWarning)
                                        {
                                            success = false;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        feedback.Message("In " + testName + " wrong kind of error!" + errorList[i].GetType() + "\n", true);
                                    }
                                }
                            }
                            XdmNode expected        = getChildElement(schemaTest, expectedNT);
                            bool    expectedSuccess = expected == null ||
                                                      expected.GetAttributeValue(validityAtt) == "valid";
                            if (success == expectedSuccess)
                            {
                                passed++;
                            }
                            else
                            {
                                failed++;
                            }
                            feedback.Feedback(passed, failed, total);
                            results.Write("<testResult set='" + testSetName +
                                          "' group='" + testGroupName +
                                          "' test='" + testName +
                                          "' validity='" + (success ? "valid" : "invalid") +
                                          (queried ? "' saxon:queried='true' saxon:bugzilla='" + bugzillaRef : "") +
                                          "' saxon:outcome='" + (success == expectedSuccess ? "same" : "different") +
                                          "'/>\n");
                        }
                        IEnumerator instanceTests = testGroup.EnumerateAxis(XdmAxis.Child, instanceTestNT);
                        while (instanceTests.MoveNext())
                        {
                            XdmNode instanceTest = (XdmNode)instanceTests.Current;
                            String  testName     = instanceTest.GetAttributeValue(nameAtt);

                            if (exception != null)
                            {
                                results.Write("<testResult set='" + testSetName +
                                              "' group='" + testGroupName +
                                              "' test='" + testName +
                                              "' validity='notKnown' saxon:outcome='notRun' saxon:comment='" + exception +
                                              "'/>\n");
                                continue;
                            }

                            bool    queried       = false;
                            XdmNode statusElement = getChildElement(instanceTest, currentNT);
                            if (statusElement != null)
                            {
                                String status = statusElement.GetAttributeValue(statusAtt);
                                queried = ("queried" == status);
                                String instanceBug = statusElement.GetAttributeValue(bugzillaAtt);
                                if (instanceBug != null)
                                {
                                    bugzillaRef = instanceBug;
                                }
                            }
                            queried |= schemaQueried;

                            Console.WriteLine("TEST INSTANCE " + testName + (queried ? " (queried)" : ""));

                            XdmNode instanceDocument = getChildElement(instanceTest, instanceDocumentNT);

                            bool success = true;
                            try
                            {
                                XdmNode instanceDoc = getLinkedDocument(instanceDocument, testConfig, true);
                            }
                            catch (Exception)
                            {
                                success = false;
                            }

                            XdmNode expected        = getChildElement(instanceTest, expectedNT);
                            bool    expectedSuccess = expected == null ||
                                                      expected.GetAttributeValue(validityAtt) == "valid";
                            if (success == expectedSuccess)
                            {
                                passed++;
                            }
                            else
                            {
                                failed++;
                            }
                            feedback.Feedback(passed, failed, total);
                            results.Write("<testResult set='" + testSetName +
                                          "' group='" + testGroupName +
                                          "' test='" + testName +
                                          "' validity='" + (success ? "valid" : "invalid") +
                                          (queried ? "' saxon:queried='true' saxon:bugzilla='" + bugzillaRef : "") +
                                          "' saxon:outcome='" + (success == expectedSuccess ? "same" : "different") +
                                          "'/>\n");
                        }
                    }
                }

                results.Write("</testSuiteResults>");
                results.Close();
            } catch (Exception e) {
                feedback.Message("Test failed: " + e.Message, true);
            }
        }