从Saxon 9.4he中的嵌入资源加载xml和xslt

我使用Saxon 9.4家庭版( Saxon-HE 9.4 .NET )来获得对XSLT 2.0和XPath 2.0以及.NET中的XQuery 1.0的支持。 当我加载没有URI的文件时,我的代码崩溃了。

  1. 是否可以在没有与加载的文档相关的URI的情况下加载xml / xsl文档?
  2. 如果没有,有没有办法为嵌入在dll文件中的元素定义URI?

任何其他解决方案也将受到赞赏,我唯一的术语是必须从dll文件中加载文件。

只要我从文件加载xml / xsl,我的代码就可以正常工作:

const string sourcePath = @"C:\test\TestInvoiceWithError.xml"; const string xsltpath = @"C:\test\UBL-T10-BiiRules.xsl"; 

当我尝试从嵌入式资源加载时,代码抛出一个exception,说明“没有提供基本URI”

 Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml"); Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl"); 

我还为具有相对路径的资源创建了Uri,这会引发exception“相对URI不支持此操作”。

 Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml", UriKind.Relative); Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative); 

这是我的代码:

 using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using System.Xml; using Microsoft.VisualStudio.TestTools.UnitTesting; using Saxon.Api; namespace TestProject1 { [TestClass] public class XsltTest { [TestMethod] public void SaxonTest() { Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml"); Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl"); Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml", UriKind.Relative); Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative); const string sourcePath = @"C:\test\TestInvoiceWithError.xml"; const string xsltpath = @"C:\test\UBL-T10-BiiRules.xsl"; Processor processor = new Processor(); XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourcePath)); XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltpath)).Load(); transformer.InitialContextNode = input; Serializer serializer = new Serializer(); StringBuilder sb = new StringBuilder(); TextWriter writer = new StringWriter(sb); serializer.SetOutputWriter(writer); transformer.Run(serializer); XmlDocument xmlDocOut = new XmlDocument(); xmlDocOut.LoadXml(sb.ToString()); XmlNodeList failedAsserts = xmlDocOut.SelectNodes("/svrl:schematron-output/svrl:failed-assert",XmlInvoiceNamespaceManager()); if (failedAsserts == null) return; foreach (XmlNode failedAssert in failedAsserts) { if (failedAssert.Attributes == null) continue; XmlAttribute typeOfError = failedAssert.Attributes["flag"]; if (typeOfError.Value.Equals("warning")) {/*Log something*/} else if (typeOfError.Value.Equals("fatal")) {/*Log something*/} } } private XmlNamespaceManager XmlInvoiceNamespaceManager() { IDictionary list = new Dictionary { {"xml", "http://www.w3.org/XML/1998/namespace"}, {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, {"xsd", "http://www.w3.org/2001/XMLSchema"}, {"udt","urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"}, {"qdt","urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"}, {"ext","urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"}, {"ccts", "urn:un:unece:uncefact:documentation:2"}, {"cbc","urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"}, {"cac","urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"}, {"inv", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"}, {"svrl", "http://purl.oclc.org/dsdl/svrl"} }; XmlNameTable xmlNameTable = new NameTable(); XmlNamespaceManager xmlInvoiceNamespaceManager = new XmlNamespaceManager(xmlNameTable); foreach (KeyValuePair ns in list) { xmlInvoiceNamespaceManager.AddNamespace(ns.Key, ns.Value); } return xmlInvoiceNamespaceManager; } protected static Stream GetEmbeddedResource(string path) { Assembly asm = Assembly.GetExecutingAssembly(); Stream stream = asm.GetManifestResourceStream(path); return stream; } } } 

我认为您可以使用Saxon从流加载,但您需要首先设置一个基本URI,以允许加载任何引用资源(如XML文档中的DTD或类似包含或导入的样式表模块)。 如果您确定没有,那么只需尝试例如

 DocumentBuilder db = processor.NewDocumentBuilder(); db.BaseUri = new Uri("file:///C:/"); XdmNode input = db.Build(xsltStream); 

显然,如果您需要在XSLT中解析也要作为嵌入式资源加载的相对URI,则需要更多工作:您需要将XmlResolver设置为支持从嵌入式资源加载资源的类,以及XSLT中的URI,用于向解析程序指示需要从资源加载的内容。 我不认为.NET框架提供了这种类型的XmlResolver,并且Uri类也不支持自定义模式。