I am using Saxon 9.4 home edition (Saxon-HE 9.4 .NET) to get support for XSLT 2.0 and XPath 2.0, and XQuery 1.0 in .NET. My code crashes when I load files without an URI.
Any other solutions will also be appreciated, my only term is that the files must be loaded from within the dll-file.
My code works perfectly as long as i load xml/xsl from file:
const string sourcePath = @"C:\test\TestInvoiceWithError.xml";
const string xsltpath = @"C:\test\UBL-T10-BiiRules.xsl";
When i try to load from embedded resource the code throws an exception stating 'No base URI supplied':
Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml");
Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl");
I have also created Uri's for resources with relative path which throws the exception 'This operation is not supported for a relative 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);
Here is my code:
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<string, string> list = new Dictionary<string, string>
{
{"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<string, string> 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;
}
}
}
I think you can load from a stream with Saxon but you need to set a base URI first that would allow to load any references resources (like a DTD in an XML document or like included or imported stylesheet modules). If you are sure you don't have that then simply try e.g.
DocumentBuilder db = processor.NewDocumentBuilder();
db.BaseUri = new Uri("file:///C:/");
XdmNode input = db.Build(xsltStream);
Obviously if you need to resolve relative URIs in the XSLT that are also to be loaded as embedded resource more work is needed: you need to set up the XmlResolver
to a class that supports loading the resource from an embedded resource, together with a scheme of URIs in the XSLT to indicate to the resolver that you need to load from a resource. I don't think the .NET framework provides such a kind of XmlResolver and the Uri class does not support a custom schema for that either.
Recently,I encountered this problem. And this is my solution.
private void test() {
Stream xsltStream = GetEmbeddedResource("TestSaxon.Resources.test.xsl");
Processor processor = new Processor();
DocumentBuilder db = processor.NewDocumentBuilder();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(xsltStream);
XdmNode xdmNode = db.Build(xmlDocument);
XsltTransformer transformer = processor.NewXsltCompiler().Compile(xdmNode).Load();
var path = AppDomain.CurrentDomain.BaseDirectory;
var input = new FileInfo(path + @"\input.xml");
var output = new FileInfo(path + @"\result.xml");
var destination = new DomDestination();
using (var inputStream = input.OpenRead())
{
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
destination.XmlDocument.Save(output.FullName);
}
protected static Stream GetEmbeddedResource(string path)
{
Assembly asm = Assembly.GetExecutingAssembly();
Stream stream = asm.GetManifestResourceStream(path);
return stream;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With