C# 将SAXON 9.5(nuget)与Schematron一起使用

C# 将SAXON 9.5(nuget)与Schematron一起使用,c#,xslt,schematron,C#,Xslt,Schematron,我正在运行以下代码: 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 transform

我正在运行以下代码:

        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);
在检查xsltSchematronStylesheet时,我得到的似乎是XSLT文件。然而,st2末端的流的长度为0。此外,MyMessageListener.Message不接收任何调用(我使用了断点)

我不确定我是否有错误的代码、错误的示例文件等。 我相信我的示例文件是正确的,但可能我有一些不好的文件或丢失了一些

有人知道为什么没有数据返回到流st2吗。如果没有,您能告诉我一个很好的简单示例,它包含所有文件和工作原理吗?

分辨率:

serializer.SetOutputStream(st2);
应该是

serializer2.SetOutputStream(st2);

我真正的潜在问题是找到在.Net中执行Schematron的简单完整的示例代码。下一个家伙就是我要找的样本。我已经尽力使这一切尽可能完整。如果我遗漏了什么,请留下评论

  • 创建单元测试项目
  • 运行Nuget命令
  • 下载Schematron文件
  • 使用包含的类和sch、xml文件
  • 运行测试程序
  • Nuget-Saxon命令行:

    Install-Package Saxon-HE 
    
    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;
    
    
            }
    
        }
    }
    
    <?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>
    
    下载最新的Schematron文件

    单元测试

    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);
    
            }
        }
    }
    
    变换类:

    Install-Package Saxon-HE 
    
    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;
    
    
            }
    
        }
    }
    
    <?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>
    
    使用系统;
    使用Microsoft.VisualStudio.TestTools.UnitTesting;
    使用System.Xml;
    使用System.Xml.XPath;
    使用System.Xml.Xsl;
    使用Saxon.Api;
    使用System.IO;
    使用System.Xml.Schema;
    使用System.Collections.Generic;
    名称空间SOAPonFHIR.Test
    {
    公共类XSLTransform
    {
    公共流转换(Uri xmluri、Uri xsluri)
    {
    //创建一个处理器实例。
    处理器=新处理器();
    //加载源文档
    XdmNode input=processor.NewDocumentBuilder().Build(xmluri);
    //为样式表创建一个转换器。
    var compiler=processor.NewXsltCompiler();
    compiler.ErrorList=new System.Collections.Generic.List();
    XsltTransformer transformer=compiler.Compile(xsluri.Load();
    if(compiler.ErrorList.Count!=0)
    抛出新异常(“异常加载xsl!”);
    //将源文档的根节点设置为初始上下文节点
    transformer.InitialContextNode=输入;
    //创建序列化程序
    Serializer Serializer=新的序列化程序();
    MemoryStream结果=新的MemoryStream();
    serializer.SetOutputStream(结果);
    //将源XML转换为System.out。
    transformer.Run(序列化程序);
    //获取字符串
    结果:位置=0;
    返回结果;
    }
    公共System.IO.Stream转换(System.IO.Stream xmlstream、System.IO.Stream xslstream)
    {
    //创建一个处理器实例。
    处理器=新处理器();
    //加载源文档
    var documentbuilder=processor.NewDocumentBuilder();
    documentbuilder.BaseUri=新Uri(“文件:/”);
    XdmNode输入=documentbuilder.Build(xmlstream);
    //为样式表创建一个转换器。
    var compiler=processor.NewXsltCompiler();
    compiler.ErrorList=new System.Collections.Generic.List();
    compiler.XmlResolver=新的XmlUrlResolver();
    XsltTransformer transformer=compiler.Compile(xslstream.Load();
    if(compiler.ErrorList.Count!=0)
    抛出新异常(“异常加载xsl!”);
    //将源文档的根节点设置为初始上下文节点
    transformer.InitialContextNode=输入;
    //创建序列化程序
    Serializer Serializer=新的序列化程序();
    MemoryStream结果=新的MemoryStream();
    serializer.SetOutputStream(结果);
    //将源XML转换为System.out。
    transformer.Run(序列化程序);
    //获取字符串
    结果:位置=0;
    返回结果;
    }
    }
    }
    
    Schematron文件

    <?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 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>
    
    
    测试ISO schematron文件。引入模式
    一章应该有一个标题
    
    XML文件

    <?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 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>
    
    
    章名
    章节内容
    第二章标题
    内容
    标题
    第三章内容
    
    结果:

    Install-Package Saxon-HE 
    
    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;
    
    
            }
    
        }
    }
    
    <?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>
    
    
    
    首先,这些反斜杠看起来可疑。URI始终包含正斜杠,而不是反斜杠。请尝试在MemoryStream上调用Close()。设置Position=0可能会删除现有内容。(我不是这里的专家,MemoryStream类总是让我困惑。)我开始认为我的xsl和/或sch和/或xml文件在某种程度上有缺陷。我发现了“iso-schematron-xslt2”,它使用了[link]中提到的“”名称空间。但是,我使用这些文件得到了相同的行为。不幸的是,iso-schematron-xslt2文件集不包含要测试的已知良好的sch和xml示例。有人能给我举一个这样的例子吗?您可以使用XMLValidatorBuddy(在试用期内)看看您的Schematron模式是否可以转换为样式表。该工具有一个从任何Schematron模式获取XSLT的命令。此外,它允许您指定转换应使用的样式表(随您提到的purl.oclc.org/dsdl/schematron ISO名称空间的样式表一起安装),并使用Saxon进行转换而且它证明了文件的有效性——至少使用了Saxon HE的内置java实现。我使用XVB从sch创建了一个样式表,并使用该样式表填充变量“xsltSchematronStylesheet”。然后,我在xml文件上运行了转换,结果仍然是流中有一个空值