Question

I am running this code:

        string path = AppDomain.CurrentDomain.BaseDirectory;

        // Uri schemaUri = new Uri(@"file:\\" + path + @"\sch\patient.sch");
        Uri totransformEE = new Uri(@"file:\\" + path + @"\po\po-schema.sch");
        Uri transformER = new Uri(@"file:\\" + path + @"\xsl\conformance1-5.xsl");

        ///////////////////////////////
        // Crate Schemtron xslt to be applied
        ///////////////////////////////
        // Create a Processor instance.
        Processor processor = new Processor();

        // Load the source document
        XdmNode input = processor.NewDocumentBuilder().Build(totransformEE);

        // Create a transformer for the stylesheet.
        XsltTransformer transformer = processor.NewXsltCompiler().Compile(transformER).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();
        MemoryStream st = new MemoryStream();
        serializer.SetOutputStream(st);

        // Transform the source XML to System.out.
        transformer.Run(serializer);

        st.Position = 0;
        System.IO.StreamReader rd = new System.IO.StreamReader(st);
        string xsltSchematronStylesheet = rd.ReadToEnd();

        System.Diagnostics.Debug.WriteLine(xsltSchematronStylesheet);

        // Load the source document
        Uri transformEE2 = new Uri(@"file:\\" + path + @"\po\po-bad.xml");

        var documentbuilder2 = processor.NewDocumentBuilder();
        XdmNode input2 = documentbuilder2.Build(transformEE2);

        ////// Create a transformer for the stylesheet.
        StringReader sr2 = new StringReader(xsltSchematronStylesheet);
        XsltTransformer transformer2 = processor.NewXsltCompiler().Compile(sr2).Load();

        // Set the root node of the source document to be the initial context node
        transformer2.InitialContextNode = input2;

        // Create a serializer
        Serializer serializer2 = new Serializer();
        MemoryStream st2 = new MemoryStream();
        serializer.SetOutputStream(st2);

        transformer2.MessageListener = new MyMessageListener();
        // Transform the source XML to System.out.
        transformer2.Run(serializer2);

        st2.Position = 0;
        System.IO.StreamReader rd2 = new System.IO.StreamReader(st2);
        string xsltSchematronResult = rd2.ReadToEnd();
        System.Diagnostics.Debug.WriteLine(xsltSchematronResult);

I get what appears to be an XSLT file when examining xsltSchematronStylesheet. However the stream at the end st2 has 0 length. Also, MyMessageListener.Message receives no calls (I used a break point).

I am not sure if I have bad code, bad sample files, etc. I believe my sample files are correct, but maybe I have bad ones or am missing some.

Does anyone know why no data is returned to the stream st2. If not can you direct me to a good simple sample that has all the files and works?

Was it helpful?

Solution

My real underlying problem was finding simple complete sample code to do Schematron in .Net. So for the next guy here is the sample I was looking for. I have tried to make this as complete as possible. If I missed something, leave a comment.

  1. Create a unit test project
  2. Run the Nuget Command
  3. Download the Schematron files
  4. Use the included classes and sch, xml files.
  5. Run the test program

Nuget Saxon Commandline:

Install-Package Saxon-HE 

Download Up to date Schematron Files http://www.schematron.com/tmp/iso-schematron-xslt2.zip

UnitTest:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace SOAPonFHIR.Test
{
    [TestClass]
    public class Schematron
    {
        [TestMethod]
        public void XSLT_SAXON_Simple_Schematron2()
        {

            ///////////////////////////////
            // Transform original Schemtron  
            ///////////////////////////////
            string path = AppDomain.CurrentDomain.BaseDirectory;

            Uri schematron = new Uri(@"file:\\" + path + @"\simple\input.sch");
            Uri schematronxsl = new Uri(@"file:\\" + path + @"\xsl_2.0\iso_svrl_for_xslt2.xsl");

            Stream schematrontransform = new Test.XSLTransform().Transform(schematron, schematronxsl);

            ///////////////////////////////
            // Apply Schemtron xslt 
            ///////////////////////////////
            FileStream xmlstream = new FileStream(path + @"\simple\input.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
            Stream results = new Test.XSLTransform().Transform(xmlstream, schematrontransform);

            System.Diagnostics.Debug.WriteLine("RESULTS");
            results.Position = 0;
            System.IO.StreamReader rd2 = new System.IO.StreamReader(results);
            string xsltSchematronResult = rd2.ReadToEnd();
            System.Diagnostics.Debug.WriteLine(xsltSchematronResult);

        }
    }
}

Transform Class:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Saxon.Api;
using System.IO;
using System.Xml.Schema;
using System.Collections.Generic;

namespace SOAPonFHIR.Test
{
    public class XSLTransform
    {
        public Stream Transform(Uri xmluri, Uri xsluri)
        {


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

            // Load the source document
            XdmNode input = processor.NewDocumentBuilder().Build(xmluri);

            // Create a transformer for the stylesheet.
            var compiler = processor.NewXsltCompiler();
            compiler.ErrorList = new System.Collections.Generic.List<Exception>();

            XsltTransformer transformer = compiler.Compile(xsluri).Load();

            if (compiler.ErrorList.Count != 0)
                throw new Exception("Exception loading xsl!");

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

            // Create a serializer
            Serializer serializer = new Serializer();
            MemoryStream results = new MemoryStream();
            serializer.SetOutputStream(results);

            // Transform the source XML to System.out.
            transformer.Run(serializer);

            //get the string
            results.Position = 0;
            return results;


        }

        public System.IO.Stream Transform(System.IO.Stream xmlstream, System.IO.Stream xslstream)
        {

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

            // Load the source document
            var documentbuilder = processor.NewDocumentBuilder();
            documentbuilder.BaseUri = new Uri("file://c:/" );
            XdmNode input = documentbuilder.Build(xmlstream);

            // Create a transformer for the stylesheet.
            var compiler = processor.NewXsltCompiler();
            compiler.ErrorList = new System.Collections.Generic.List<Exception>();
            compiler.XmlResolver = new XmlUrlResolver();
            XsltTransformer transformer = compiler.Compile(xslstream).Load();

            if (compiler.ErrorList.Count != 0)
                throw new Exception("Exception loading xsl!");

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

            // Create a serializer
            Serializer serializer = new Serializer();
            MemoryStream results = new MemoryStream();
            serializer.SetOutputStream(results);

            // Transform the source XML to System.out.
            transformer.Run(serializer);

            //get the string
            results.Position = 0;
            return results;


        }

    }
}

Schematron File

<?xml version="1.0" encoding="utf-8"?>
<iso:schema
  xmlns="http://purl.oclc.org/dsdl/schematron" 
  xmlns:iso="http://purl.oclc.org/dsdl/schematron"
  xmlns:dp="http://www.dpawson.co.uk/ns#"
  queryBinding='xslt2'
  schemaVersion='ISO19757-3'>

  <iso:title>Test ISO schematron file. Introduction mode</iso:title>
  <iso:ns prefix='dp' uri='http://www.dpawson.co.uk/ns#'/> 

  <iso:pattern>
    <iso:rule context="chapter">

      <iso:assert
         test="title">A chapter should have a title</iso:assert>  
    </iso:rule>
  </iso:pattern>


</iso:schema>

XML File

<?xml version="1.0" encoding="utf-8" ?>
<doc>
  <chapter id="c1">
    <title>chapter title</title>  
    <para>Chapter content</para>
  </chapter>

  <chapter id="c2">
    <title>chapter 2 title</title>
    <para>Content</para>           
  </chapter>

  <chapter id="c3">
    <title>Title</title>
    <para>Chapter 3 content</para>
  </chapter>
</doc>

Results:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                        xmlns:xs="http://www.w3.org/2001/XMLSchema"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        xmlns:saxon="http://saxon.sf.net/"
                        xmlns:schold="http://www.ascc.net/xml/schematron"
                        xmlns:iso="http://purl.oclc.org/dsdl/schematron"
                        xmlns:xhtml="http://www.w3.org/1999/xhtml"
                        xmlns:dp="http://www.dpawson.co.uk/ns#"
                        title="Test ISO schematron file. Introduction mode"
                        schemaVersion="ISO19757-3"><!--   
           
           
         -->
   <svrl:ns-prefix-in-attribute-values uri="http://www.dpawson.co.uk/ns#" prefix="dp"/>
   <svrl:active-pattern document="file:///c:/"/>
   <svrl:fired-rule context="chapter"/>
   <svrl:fired-rule context="chapter"/>
   <svrl:fired-rule context="chapter"/>
</svrl:schematron-output>

OTHER TIPS

Resolution:

serializer.SetOutputStream(st2);

should be

serializer2.SetOutputStream(st2);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top