我正在运行此代码:
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。如果没有,您能否指导我找到一个包含所有文件和作品的简单示例?
最佳答案
我真正的潜在问题是找到简单的完整示例代码来在 .Net 中执行 Schematron。所以这里的下一个人是我正在寻找的样本。我试图使这尽可能完整。如果我错过了什么,请发表评论。
Nuget Saxon 命令行:
Install-Package Saxon-HE
下载最新的 Schematron 文件
http://www.schematron.com/tmp/iso-schematron-xslt2.zip
单元测试 :
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);
}
}
}
变换类:
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 文件
<?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 文件
<?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>
结果:
<?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>
关于c# - 将 SAXON 9.5 (nuget) 与 Schematron 结合使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22059562/