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?
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.
- Create a unit test project
- Run the Nuget Command
- Download the Schematron files
- Use the included classes and sch, xml files.
- 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>
Resolution:
serializer.SetOutputStream(st2);
should be
serializer2.SetOutputStream(st2);
来源:https://stackoverflow.com/questions/22059562/using-saxon-9-5-nuget-with-schematron