using System;
using System.IO;
using System.Collections;
using System.Xml;
using Saxon.Api;



public class XsltExamples {


    public static void Main(String[] argv) {

        String test = "all";

        if (argv.Length > 0) {
            test = argv[0];
        }

        String samplesDir;
        
        if (argv.Length > 1) {
            samplesDir = argv[1];
        } 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/";
                }
            }
        }
        
        String dir = samplesDir + "trax/";

        String foo_xml = dir + "xml/foo.xml";
        String foo_xsl = dir + "xsl/foo.xsl";
        String baz_xml = dir + "xml/baz.xml";
        String baz_xsl = dir + "xsl/baz.xsl";
        String foo2_xsl = dir + "xsl/foo2.xsl";
        String foo3_xsl = dir + "xsl/foo3.xsl";
        String text_xsl = dir + "xsl/text.xsl";
        String embedded_xml = dir + "xml/embedded.xml";
        String multidoc_xsl = dir + "xsl/multidoc.xsl";


        if (test == "all" || test == "ExampleSimple1") {
            Console.WriteLine("\n\n==== ExampleSimple1 ====");

            try {
                ExampleSimple1(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleSimple2") {
            Console.WriteLine("\n\n==== ExampleSimple2 ====");

            try {
                ExampleSimple2(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }


        if (test == "all" || test == "ExampleFromReader") {
            Console.WriteLine("\n\n==== ExampleFromReader ====");

            try {
                ExampleFromReader(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleUseTemplatesObj") {
            Console.WriteLine("\n\n==== ExampleUseTemplatesObj ====");

            try {
                ExampleUseTemplatesObj(foo_xml, baz_xml,
                                       foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleSAXResult") {
            Console.WriteLine("\n\n==== ExampleSAXResult ====");

            try {
                ExampleSAXResult(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleXMLReader") {
            Console.WriteLine("\n\n==== ExampleXMLReader ====");

            try {
                ExampleXMLReader(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleXMLFilter") {
            Console.WriteLine("\n\n==== ExampleXMLFilter ====");

            try {
                ExampleXMLFilter(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleXMLFilterChain") {
            Console.WriteLine("\n\n==== ExampleXMLFilterChain ====");

            try {
                ExampleXMLFilterChain(foo_xml, foo_xsl,
                                      foo2_xsl, foo3_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleSaxonToSaxon") {
            Console.WriteLine("\n\n==== ExampleSaxonToSaxon ====");

            try {
                ExampleSaxonToSaxon(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleSaxonToSaxonNonRoot") {
            Console.WriteLine("\n\n==== ExampleSaxonToSaxonNonRoot ====");

            try {
                ExampleSaxonToSaxonNonRoot(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleDOMtoDOM") {
            Console.WriteLine("\n\n==== ExampleDOMtoDOM ====");

            try {
                ExampleDOMtoDOM(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleParam") {
            Console.WriteLine("\n\n==== ExampleParam ====");

            try {
                ExampleParam(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleTransformerReuse") {
            Console.WriteLine("\n\n==== ExampleTransformerReuse ====");

            try {
                ExampleTransformerReuse(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleOutputProperties") {
            Console.WriteLine("\n\n==== ExampleOutputProperties ====");

            try {
                ExampleOutputProperties(foo_xml, foo_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleUseAssociated") {
            Console.WriteLine("\n\n==== ExampleUseAssociated ====");

            try {
                ExampleUseAssociated(foo_xml);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleUseEmbedded") {
            Console.WriteLine("\n\n==== ExampleUseEmbedded ====");

            try {
                ExampleUseAssociated(embedded_xml);
            } catch (Exception ex) {
                handleException(ex);
            }
        }
        
        if (test == "all" || test == "ExampleCapturingErrors") {
            Console.WriteLine("\n\n==== ExampleCapturingErrors ====");

            try {
                ExampleCapturingErrors();
            } catch (Exception ex) {
                handleException(ex);
            }
        }        


        if (test == "all" || test == "ExampleUsingURIResolver") {
            Console.WriteLine("\n\n==== ExampleUsingURIResolver ====");

            try {
                ExampleUsingURIResolver(foo_xml, text_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleMultipleOutput") {
            Console.WriteLine("\n\n==== ExampleMultipleOutput ====");

            try {
                ExampleMultipleOutput(foo_xml, multidoc_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        if (test == "all" || test == "ExampleUsingOutputURIResolver") {
            Console.WriteLine("\n\n==== ExampleUsingOutputURIResolver ====");

            try {
                ExampleUsingOutputURIResolver(foo_xml, multidoc_xsl);
            } catch (Exception ex) {
                handleException(ex);
            }
        }

        Console.WriteLine("\n==== done! ====");
    }

    /**
     * Show the simplest possible transformation from URI of source document
     * to output stream.
     */
    public static void ExampleSimple1(String sourceUri, String xsltUri) {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));

        // Create a transformer for the stylesheet.
        XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltUri)).Load();
        
        // Set the root node of the source document to be the initial context node
        transformer.InitialContextNode = input;
        
        // Create a serializer
        Serializer serializer = new Serializer();
        serializer.SetOutputWriter(Console.Out);
        
        // Transform the source XML to System.out.
        transformer.Run(serializer);
    }


    /**
     * Show the simplest possible transformation from File
     * to a File.
     */
    public static void ExampleSimple2(String sourceUri, String xsltUri) {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));

        // Create a transformer for the stylesheet.
        XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltUri)).Load();
        
        // Set the root node of the source document to be the initial context node
        transformer.InitialContextNode = input;
        
        // Create a serializer
        Serializer serializer = new Serializer();
        serializer.SetOutputStream(new FileStream("ExampleSimple2.out", FileMode.Create, FileAccess.Write));
        
        // Transform the source XML to System.out.
        transformer.Run(serializer);

        Console.WriteLine("\nOutput written to ExampleSimple2.out\n");
    }


    /**
     * Show simple transformation from reader to output stream.  In general
     * this use case is discouraged, since the XML encoding can not be
     * processed.
     */
    public static void ExampleFromReader(String sourceUri, String xsltUri) {

/*        // Create a transform factory instance.
        TransformerFactory tfactory = TransformerFactory.newInstance();

        // Note that in this case the XML encoding can not be processed!
        Reader       xslReader = new BufferedReader(new FileReader(xsltUri));
        StreamSource xslSource = new StreamSource(xslReader);

        // Note that if we don't do this, relative URLs can not be resolved correctly!
        xslSource.setSystemId(xsltUri);

        // Create a transformer for the stylesheet.
        Transformer transformer = tfactory.newTransformer(xslSource);

        // Note that in this case the XML encoding can not be processed!
        Reader       xmlReader = new BufferedReader(new FileReader(sourceUri));
        StreamSource xmlSource = new StreamSource(xmlReader);

        // The following line would be needed if the source document contained
        // a relative URL
        // xmlSource.setSystemId(sourceUri);

        // Transform the source XML to System.out.
        transformer.transform(xmlSource, new StreamResult(System.out));*/
    }

    /**
     * Perform a transformation using a compiled stylesheet (a Templates object)
     */
    public static void ExampleUseTemplatesObj(
            String sourceUri1, String sourceUri2, String xsltUri) {

        // Create a Processor instance.
        Processor processor = new Processor();
              
        // Create a compiled stylesheet
        XsltExecutable templates = processor.NewXsltCompiler().Compile(new Uri(xsltUri));
       
        // Note: we could actually use the same XSltTransformer in this case.
        // But in principle, the two transformations could be done in parallel in separate threads.
        
        // Do the first transformation
        Console.WriteLine("\n\n----- transform of " + sourceUri1 + " -----");
        XsltTransformer transformer1 = templates.Load();
        transformer1.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(sourceUri1));
        transformer1.Run(new Serializer());     // default destination is Console.Out

        // Do the second transformation
        Console.WriteLine("\n\n----- transform of " + sourceUri2 + " -----");
        XsltTransformer transformer2 = templates.Load();
        transformer2.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(sourceUri2));
        transformer2.Run(new Serializer());     // default destination is Console.Out        

    }


    /**
     * Send output to a user-specified ContentHandler.
     */

    public static void ExampleSAXResult(
            String sourceUri, String xsltUri) {

 /*       TransformerFactory tfactory = TransformerFactory.newInstance();

        // Does this factory support SAX features?
        if (tfactory.getFeature(SAXResult.FEATURE)) {

            // Get a transformer in the normal way:
            Transformer transformer =
                tfactory.newTransformer(new StreamSource(xsltUri));

            // Get the source as a StreamSource
            Reader       xmlReader = new BufferedReader(new FileReader(sourceUri));
            StreamSource xmlSource = new StreamSource(xmlReader);

            // Set the result handling to be a serialization to System.out.
            Result result = new SAXResult(new ExampleContentHandler());

            // Do the transformation
            transformer.transform(xmlSource, result);

        } else {
            Console.WriteLine(
                "Can't do ExampleSAXResult because tfactory is not a SAXTransformerFactory");
        }*/
    }


    /**
     * Show the Transformer as a SAX2 XMLReader.  An XMLFilter obtained
     * from newXMLFilter should act as a transforming XMLReader if setParent is not
     * called.  Internally, an XMLReader is created as the parent for the XMLFilter.
     */
    public static void ExampleXMLReader(String sourceUri, String xsltUri) {

     /*   TransformerFactory tfactory = TransformerFactory.newInstance();

        if (tfactory.getFeature(SAXSource.FEATURE)) {
            XMLReader reader =
                ((SAXTransformerFactory) tfactory)
                    .newXMLFilter(new StreamSource(new File(xsltUri)));

            reader.setContentHandler(new ExampleContentHandler());
            reader.parse(new InputSource(new File(sourceUri).toURL().toString()));
        } else {
            Console.WriteLine("tfactory does not support SAX features!");
        }*/
    }

    /**
     * Show the Transformer as a simple XMLFilter.  This is pretty similar
     * to ExampleXMLReader, except that here the parent XMLReader is created
     * by the caller, instead of automatically within the XMLFilter.  This
     * gives the caller more direct control over the parent reader.
     */
    public static void ExampleXMLFilter(String sourceUri, String xsltUri) {

  /*      TransformerFactory tfactory = TransformerFactory.newInstance();
        XMLReader reader   = makeXMLReader();


        // The transformer will use a SAX parser as it's reader.

        try {
            reader.setFeature(
                "http://xml.org/sax/features/namespace-prefixes", true);
        } catch (SAXException se) {
            System.err.println("SAX Parser doesn't report namespace prefixes!");
            throw se;
        }

        XMLFilter filter =
            ((SAXTransformerFactory) tfactory)
                .newXMLFilter(new StreamSource(new File(xsltUri)));

        filter.setParent(reader);
        filter.setContentHandler(new ExampleContentHandler());

        // Now, when you call transformer.parse, it will set itself as
        // the content handler for the parser object (it's "parent"), and
        // will then call the parse method on the parser.
        filter.parse(new InputSource(new File(sourceUri).toURL().toString()));*/
    }

    /**
     * This Example shows how to chain events from one Transformer
     * to another transformer, using the Transformer as a
     * SAX2 XMLFilter/XMLReader.
     */
    public static void ExampleXMLFilterChain(
            String sourceUri, String xsltUri_1, String xsltUri_2, String xsltUri_3) {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        
        // Create a compiler
        XsltCompiler compiler = processor.NewXsltCompiler();
        
        // Compile all three stylesheets
        XsltTransformer transformer1 = compiler.Compile(new Uri(xsltUri_1)).Load();
        XsltTransformer transformer2 = compiler.Compile(new Uri(xsltUri_2)).Load();
        XsltTransformer transformer3 = compiler.Compile(new Uri(xsltUri_2)).Load();
        
        // Now run them in series
        transformer1.InitialContextNode = input;
        XdmDestination results1 = new XdmDestination();
        transformer1.Run(results1);
        Console.WriteLine("After phase 1:");
        Console.WriteLine(results1.XdmNode.OuterXml);
        
        transformer2.InitialContextNode = results1.XdmNode;
        XdmDestination results2 = new XdmDestination();
        transformer2.Run(results2);
        Console.WriteLine("After phase 2:");
        Console.WriteLine(results2.XdmNode.OuterXml);
        
        transformer3.InitialContextNode = results2.XdmNode;
        //TextWriterDestination results3 = new TextWriterDestination(new XmlTextWriter(Console.Out));
        XdmDestination results3 = new XdmDestination();
        transformer3.Run(results3);
        Console.WriteLine("After phase 3:");
        Console.WriteLine(results3.XdmNode.OuterXml);        
        
    }

    /**
     * Show how to transform a Saxon tree into another Saxon tree.
     */
    public static void ExampleSaxonToSaxon(String sourceUri, String xsltUri) {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        
        // Create a compiler
        XsltCompiler compiler = processor.NewXsltCompiler();
        
        // Compile the stylesheet
        XsltTransformer transformer = compiler.Compile(new Uri(xsltUri)).Load();
        
        // Run the transformation
        transformer.InitialContextNode = input;
        XdmDestination result = new XdmDestination();
        transformer.Run(result);
        
        // Serialize the result so we can see that it worked
        StringWriter sw = new StringWriter();
        result.XdmNode.WriteTo(new XmlTextWriter(sw));
        Console.WriteLine(sw.ToString());
        
                // Note: we don't do 
                //   result.XdmNode.WriteTo(new XmlTextWriter(Console.Out));
                // because that results in the Console.out stream being closed, 
                // with subsequent attempts to write to it being rejected.

    }

    /**
     * Show how to transform a tree starting at a node other than the root.
     */
    public static void ExampleSaxonToSaxonNonRoot(String sourceUri, String xsltUri) {

         // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        
        // Navigate to the first grandchild
        XPathSelector eval = processor.NewXPathCompiler().Compile("/*/*[1]").Load();
        eval.ContextItem = input;
        input = (XdmNode)eval.EvaluateSingle(); 
        
        // Create an XSLT compiler
        XsltCompiler compiler = processor.NewXsltCompiler();
        
        // Compile the stylesheet
        XsltTransformer transformer = compiler.Compile(new Uri(xsltUri)).Load();
        
        // Run the transformation
        transformer.InitialContextNode = input;
        XdmDestination result = new XdmDestination();
        transformer.Run(result);
        
        // Serialize the result so we can see that it worked
        Console.WriteLine(result.XdmNode.OuterXml);
 
    }


    /**
     * Show how to transform a DOM tree into another DOM tree.
     * This uses the javax.xml.parsers to parse an XML file into a
     * DOM, and create an output DOM. In this Example, Saxon uses a
     * third-party DOM as both input and output.
     */
    public static void ExampleDOMtoDOM(String sourceUri, String xsltUri) {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document (in practice, it would already exist as a DOM)
        XmlDocument doc = new XmlDocument();
        doc.Load(new XmlTextReader(sourceUri));
        XdmNode input = processor.NewDocumentBuilder().Build(doc);
        
        // Create a compiler
        XsltCompiler compiler = processor.NewXsltCompiler();
        
        // Compile the stylesheet
        XsltTransformer transformer = compiler.Compile(new Uri(xsltUri)).Load();
        
        // Run the transformation
        transformer.InitialContextNode = input;
        DomDestination result = new DomDestination();
        transformer.Run(result);
        
        // Serialize the result so we can see that it worked
        Console.WriteLine(result.XmlDocument.OuterXml);
    }


    /**
     * This shows how to set a parameter for use by the stylesheet. Use
     * two transformers to show that different parameters may be set
     * on different transformers.
     */
    public static void ExampleParam(String sourceUri, String xsltUri)  {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        
        // Compile the stylesheet
        XsltExecutable exec = processor.NewXsltCompiler().Compile(new Uri(xsltUri));
        
        // Create two transformers with different parameters
        XsltTransformer transformer1 = exec.Load();
        XsltTransformer transformer2 = exec.Load();
        
        transformer1.SetParameter(new QName("", "", "a-param"), new XdmAtomicValue("hello to you!"));
        transformer2.SetParameter(new QName("", "", "a-param"), new XdmAtomicValue("goodbye to you!"));
        
        // Now run them both
        transformer1.InitialContextNode = input;
        XdmDestination results1 = new XdmDestination();
        transformer1.Run(results1);
        
        transformer2.InitialContextNode = input;
        XdmDestination results2 = new XdmDestination();
        transformer2.Run(results2);
        
        Console.WriteLine("1: " + results1.XdmNode.StringValue);
        Console.WriteLine("2: " + results2.XdmNode.StringValue);
    }

    /**
     * Show the that a transformer can be reused, and show resetting
     * a parameter on the transformer. 
     */
    public static void ExampleTransformerReuse(String sourceUri, String xsltUri)  {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        
        // Compile the stylesheet
        XsltExecutable exec = processor.NewXsltCompiler().Compile(new Uri(xsltUri));
        
        // Create a transformer 
        XsltTransformer transformer = exec.Load();

        // Run it once        
        transformer.SetParameter(new QName("", "", "a-param"), new XdmAtomicValue("hello to you!"));
        transformer.InitialContextNode = input;
        XdmDestination results = new XdmDestination();
        transformer.Run(results);
        Console.WriteLine("1: " + results.XdmNode.StringValue);
        
        // Run it again        
        transformer.SetParameter(new QName("", "", "a-param"), new XdmAtomicValue("hello to me!"));
        transformer.InitialContextNode = input;
        results.Reset();
        transformer.Run(results);
        Console.WriteLine("2: " + results.XdmNode.StringValue);        
        
    }

    /**
     * Show how to override output properties.
     */
    public static void ExampleOutputProperties(String sourceUri, String xsltUri)  {

  /*      TransformerFactory tfactory  = TransformerFactory.newInstance();
        Templates          templates =
            tfactory.newTemplates(new StreamSource(new File(xsltUri)));
        Properties         oprops    = templates.getOutputProperties();
        oprops.put(OutputKeys.INDENT, "yes");

        Transformer transformer = templates.newTransformer();

        transformer.setOutputProperties(oprops);
        transformer.transform(new StreamSource(new File(sourceUri)),
                              new StreamResult(System.out));  */
    }

    /**
     * Show how to get stylesheets that are associated with a given
     * xml document via the xml-stylesheet PI (see http://www.w3.org/TR/xml-stylesheet/).
     */
    public static void ExampleUseAssociated(String sourceUri)  {

        // Create a Processor instance.
        Processor processor = new Processor();
        XsltExecutable exec;
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
        Console.WriteLine("=============== source document ===============");
        Console.WriteLine(input.OuterXml);
        Console.WriteLine("=========== end of source document ============");

        // Navigate to the xml-stylesheet processing instruction having the pseudo-attribute type=text/xsl;
        // then extract the value of the href pseudo-attribute if present
        
        String path = @"/processing-instruction(xml-stylesheet)[matches(.,'type\s*=\s*[''""]text/xsl[''""]')]" +
                @"/replace(., '.*?href\s*=\s*[''""](.*?)[''""].*', '$1')";
        
        XPathSelector eval = processor.NewXPathCompiler().Compile(path).Load();
        eval.ContextItem = input;
        XdmAtomicValue hrefval = (XdmAtomicValue)eval.EvaluateSingle();
        Console.WriteLine("evaluated");
        String href = hrefval.ToString();
        
        if (href == null || href == "") {
            Console.WriteLine("No suitable xml-stylesheet processing instruction found");
            return;
            
        } else if (href[0] == '#') {
            
            // The stylesheet is embedded in the source document and identified by a URI of the form "#id"
            
            Console.WriteLine("Locating embedded stylesheet with href = " + href);
            String idpath = "id('" + href.Substring(1) + "')";
            eval = processor.NewXPathCompiler().Compile(idpath).Load();
            eval.ContextItem = input;
            XdmNode node = (XdmNode)eval.EvaluateSingle();
            if (node == null) {
                Console.WriteLine("No element found with ID " + href.Substring(1));
                return;
            }
            exec = processor.NewXsltCompiler().Compile(node);

        } else {
            
            // The stylesheet is in an external document
            
            Console.WriteLine("Locating stylesheet at uri = " + new Uri(input.BaseUri, href));
                    
            // Fetch and compile the referenced stylesheet
            exec = processor.NewXsltCompiler().Compile(new Uri(input.BaseUri, href.ToString()));
        }
        
        // Create a transformer 
        XsltTransformer transformer = exec.Load();

        // Run it       
        transformer.SetParameter(new QName("", "", "a-param"), new XdmAtomicValue("hello to you!"));
        transformer.InitialContextNode = input;
        XdmDestination results = new XdmDestination();
        transformer.Run(results);
        Console.WriteLine("1: " + results.XdmNode.StringValue);

    }
    

    /**
     * Show a stylesheet compilation in which errors are captured for processing by
     * the calling application.
     */

    public static void ExampleCapturingErrors()  {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Create the XSLT Compiler
        XsltCompiler compiler = processor.NewXsltCompiler();
        
        // Create a list to hold the error information
        compiler.ErrorList = new ArrayList();
        
        // Define a stylesheet containing errors
        String stylesheet =
            "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\n" +
            "<xsl:template name='fff:template'>\n" +
            "  <xsl:value-of select='32'/>\n" +
            "</xsl:template>\n" +
            "<xsl:template name='main'>\n" +
            "  <xsl:value-of select='$var'/>\n" +
            "</xsl:template>\n" +            
            "</xsl:stylesheet>";
        
            
        // Attempt to compile the stylesheet and display the errors
        try {
            compiler.BaseUri = "http://localhost/stylesheet";
            compiler.Compile(new XmlTextReader(new StringReader(stylesheet)));
            Console.WriteLine("Stylesheet compilation succeeded");
        } catch (Exception) {
            Console.WriteLine("Stylesheet compilation failed with " + compiler.ErrorList.Count + " errors");
            foreach (StaticError error in compiler.ErrorList) {
                Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
            }
        }    

    }

    /**
     * Show a transformation using a user-written URI Resolver.
     */

    public static void ExampleUsingURIResolver(String sourceUri, String xsltUri)  {

        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));

        // Create a transformer for the stylesheet.
        XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltUri)).Load();
        
        // Set the root node of the source document to be the initial context node
        transformer.InitialContextNode = input;
        
        // Set the user-written XmlResolver
        transformer.InputXmlResolver = new UserXmlResolver();
        
        // Create a serializer
        Serializer serializer = new Serializer();
        serializer.SetOutputWriter(Console.Out);
        
        // Transform the source XML to System.out.
        transformer.Run(serializer);

    }


    /**
    * A sample XmlResolver. This handles a URI ending with ".txt". It loads the
    * text file identified by the URI, assuming it is in ISO-8859-1 encoding,
    * and wraps it in a containing doc element.
    * If the URI doesn't end with ".txt", it delegates processing
    * to the standard XmlResolver.
    */

    public class UserXmlResolver : XmlUrlResolver {
        
        public override object GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn) {
            Stream input = (Stream)base.GetEntity(absoluteUri, role, ofObjectToReturn);
            if (absoluteUri.ToString().EndsWith(".txt")) {
                StreamReader reader = new StreamReader(input);
                String content = reader.ReadToEnd();
                content = content.Replace("&", "&amp;");
                content = content.Replace("<", "&lt;");
                content = content.Replace(">", "&gt;");
                content = "<doc>" + content + "</doc>";
                return new StringReader(content);
            } else {
                return input;
            }      
        }
    } 

    /**
     * Show a transformation using a user-written output URI Resolver.
     */

    public static void ExampleMultipleOutput(String sourceUri, String xsltUri)  {
        // Create a Processor instance.
        Processor processor = new Processor();
        
        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));

        // Create a transformer for the stylesheet.
        XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltUri)).Load();
        
        // Set the root node of the source document to be the initial context node
        transformer.InitialContextNode = input;
        
        // Create a serializer
        Serializer serializer = new Serializer();
        serializer.SetOutputWriter(Console.Out);
        
        // Transform the source XML to System.out.
        transformer.Run(serializer);
   

    }

    /**
     * Show a transformation using a user-written output URI Resolver.
     */

    public static void ExampleUsingOutputURIResolver(String sourceUri, String xsltUri)  {

   

    }



    private static void handleException(Exception ex) {

        Console.WriteLine("EXCEPTION: " + ex);
        Console.WriteLine(ex.StackTrace);


    }


}
