Project

Profile

Help

UriFormatException when load XSLT from Stream

Added by Anonymous about 14 years ago

Legacy ID: #8106443 Legacy Poster: Ross B. (rossbrower)

Getting a System.UriFormatException when loading from a stream. The resource in question is an "Embedded Resource" in a .net project. Using Saxon HE 9.2.0.2. As a workaround I'm loading the transform into an XmlDocument and going from there. private static readonly XsltCompiler sXsltCompiler; ... ... private static XsltTransformer LoadFromAssembly(Assembly assembly, string fileName) { string resourceName = string.Format("Schematron.Saxon.{0}", fileName); using (Stream stream = assembly.GetManifestResourceStream(resourceName)) { return sXsltCompiler.Compile(stream).Load(); } } Exception: System.UriFormatException Message: "Invalid URI: The format of the URI could not be determined." Stack: at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind) at System.Uri..ctor(String uriString) at net.sf.saxon.dotnet.DotNetURIResolver.makeAbsolute(String href, String base) at net.sf.saxon.dotnet.DotNetURIResolver.resolve(String href, String base) at net.sf.saxon.style.XSLGeneralIncorporate.getIncludedStylesheet(XSLStylesheet importer, Int32 precedence) at net.sf.saxon.style.XSLStylesheet.spliceIncludes() at net.sf.saxon.style.XSLStylesheet.preprocess() at net.sf.saxon.PreparedStylesheet.setStylesheetDocument(DocumentImpl doc, StyleNodeFactory snFactory) at net.sf.saxon.PreparedStylesheet.prepare(Source styleSource) at net.sf.saxon.TransformerFactoryImpl.newTemplates(Source source, CompilerInfo info) at Saxon.Api.XsltCompiler.Compile(Stream input) at Schematron.Saxon.SaxonSchematron.LoadFromAssembly(Assembly assembly, String fileName) in C:\Azaleos\Tools\Schematron\Schematron.Saxon\SaxonSchematron.cs:line 64


Replies (4)

Please register to reply

RE: UriFormatException when load XSLT from Stream - Added by Anonymous about 14 years ago

Legacy ID: #8106626 Legacy Poster: Ross B. (rossbrower)

To add some background, the file causing the exception (iso_svrl_for_xslt2.xsl) is trying to reference another stylesheet (iso_schematron_skeleton_for_saxon.xsl). It would seem that since the uri of the original stylesheet is in the form assemblyName.fileName saxon likely can't determine where the file came from since it does not actually exist, therefore it cannot guess at the location of the referenced stylesheet. The .NET equivalent of loading XslCompiledTransform.Load(stream) is able to figure this out. Perhaps Saxon should use the executing assembly location to build the uri in this situation. Anyways my original workaround of loading the resource into an XmlDocument did not solve the problem because the same issue exists in that situation. Going to try loading an absolute uri and see if that will work.

RE: UriFormatException when load XSLT from Stream - Added by Anonymous about 14 years ago

Legacy ID: #8106750 Legacy Poster: Ross B. (rossbrower)

Ok found a workaround, assuming that the stylesheets in question are present in the output of your project: Assembly assembly = Assembly.GetExecutingAssembly(); string directory = new FileInfo(assembly.Location).Directory.FullName; var uri = new Uri(Path.Combine(directory, fileName), UriKind.Absolute); XsltTransformer t = sXsltCompiler.Compile(uri).Load(); This is a little nasty but it works...

RE: UriFormatException when load XSLT from Stream - Added by Anonymous about 14 years ago

Legacy ID: #8106776 Legacy Poster: Michael Kay (mhkay)

The documentation of XsltCompiler.Compile is clear (although it misspells the property name): "If the stylesheet contains any xsl:include or xsl:import declarations, then the BaseURI property must be set to allow these to be resolved." You haven't shown enough code to show whether the BaseUri property has been initialized: I suspect it hasn't. If it isn't initialized, there is no way Saxon can know where the stylesheet is, or where to find included/imported stylesheets that are located relative to the main stylesheet.

RE: UriFormatException when load XSLT from Stream - Added by Anonymous about 14 years ago

Legacy ID: #8106827 Legacy Poster: Ross B. (rossbrower)

Well I'm not a huge reader of documentation, don't learn anything that way ;). That helped though, thanks. Basically I was building a small dll that handled the several steps involved in a Schematron validation. Because everything in the Schematron distro is an xsl or xhtml file and .NET does not propagate these file dependencies, I did not want to have to add these files to each project that uses my new dll. I finally managed to get together a hacky class that gets all the files in the right place. [code] using System; using System.IO; using System.Reflection; using System.Xml; using Saxon.Api; namespace Schematron.Saxon { public class SaxonSchematron { private const string RESOURCE_FORMAT = "Schematron.Saxon.{0}"; private const string ISO_DSDL_INCLUDE = "iso_dsdl_include.xsl"; private const string ISO_ABSTRACT_EXPAND = "iso_abstract_expand.xsl"; private const string ISO_SVRL_FOR_XSLT2 = "iso_svrl_for_xslt2.xsl"; private const string ISO_SCHEMATRON_SKELETON_FOR_SAXON = "iso_schematron_skeleton_for_saxon.xsl"; private const string ISO_SCHEMATRON_MESSAGE = "iso_schematron_message_xslt2.xsl"; private const string SCH_MESSAGES_DE = "sch-messages-de.xhtml"; private const string SCH_MESSAGES_EN = "sch-messages-en.xhtml"; private const string SCH_MESSAGES_FR = "sch-messages-fr.xhtml"; private static readonly DocumentBuilder sDocumentBuilder; private static readonly Processor sProcessor; private static readonly XsltCompiler sXsltCompiler; private static readonly XsltTransformer sInclusionTransform; private static readonly XsltTransformer sExpansionTransform; private static readonly XsltTransformer sSvrlTransform; static SaxonSchematron() { sProcessor = new Processor(); sXsltCompiler = sProcessor.NewXsltCompiler(); sDocumentBuilder = sProcessor.NewDocumentBuilder(); Assembly assembly = Assembly.GetExecutingAssembly(); CopyFileIfNeeded(assembly, ISO_SCHEMATRON_SKELETON_FOR_SAXON); CopyFileIfNeeded(assembly, ISO_SCHEMATRON_MESSAGE); CopyFileIfNeeded(assembly, SCH_MESSAGES_DE); CopyFileIfNeeded(assembly, SCH_MESSAGES_EN); CopyFileIfNeeded(assembly, SCH_MESSAGES_FR); CopyFileIfNeeded(assembly, ISO_DSDL_INCLUDE); CopyFileIfNeeded(assembly, ISO_ABSTRACT_EXPAND); CopyFileIfNeeded(assembly, ISO_SVRL_FOR_XSLT2); sInclusionTransform = LoadFromFile(ISO_DSDL_INCLUDE); sExpansionTransform = LoadFromFile(ISO_ABSTRACT_EXPAND); sSvrlTransform = LoadFromFile(ISO_SVRL_FOR_XSLT2); } private static void CopyFileIfNeeded(Assembly assembly, string resourceName) { if (!File.Exists(resourceName)) { var document = new XmlDocument(); string resource = string.Format(RESOURCE_FORMAT, resourceName); using (Stream stream = assembly.GetManifestResourceStream(resource)) { document.Load(stream); } document.Save(resourceName); } } private static XsltTransformer LoadFromFile(string fileName) { string dir = new FileInfo(fileName).Directory.FullName; sXsltCompiler.BaseUri = new Uri(dir); return sXsltCompiler.Compile(new Uri(Path.Combine(dir, fileName))).Load(); } public static XdmNode Transform(XdmNode schemaDoc, XdmNode targetDoc) { schemaDoc = Transform(schemaDoc, sInclusionTransform); schemaDoc = Transform(schemaDoc, sExpansionTransform); schemaDoc = Transform(schemaDoc, sSvrlTransform); var transform = sXsltCompiler.Compile(schemaDoc).Load(); return Transform(targetDoc, transform); } public static XmlDocument Transform(XmlDocument schemaDoc, XmlDocument targetDoc) { XdmNode result = Transform(sDocumentBuilder.Wrap(schemaDoc), sDocumentBuilder.Wrap(targetDoc)); var ret = new XmlDocument(); ret.LoadXml(result.ToString()); return ret; } public static string Transform(string schemaXml, string targetXml) { var schemaDoc = new XmlDocument(); schemaDoc.LoadXml(schemaXml); var targetDoc = new XmlDocument(); targetDoc.LoadXml(targetXml); XdmNode result = Transform(sDocumentBuilder.Wrap(schemaDoc), sDocumentBuilder.Wrap(targetDoc)); return result.ToString(); } private static XdmNode Transform(XdmNode target, XsltTransformer transform) { transform.InitialContextNode = target; var result = new XdmDestination(); transform.Run(result); return result.XdmNode; } } } [/code]

    (1-4/4)

    Please register to reply