XSLT document () relative path to IIS.exe

I have a .NET WebApi project with two files, both of which are marked as embedded resources and deployed along with the application. The files are also located in the same directory in the deployed application:

  • ./XSL/transform.xslt
  • ./XSL/schema.xsd

The xslt file should load the xsd file using the document () function:

<xsl:template match="*[not(local-name() = document('schema.xsd')//xs:element/@name)]" />

<xsl:template match="@*[not(local-name() = document('schema.xsd')//xs:attribute/@name)]" />

      

Unfortunately, I get a runtime exception, which indicates that the relative path that is resolved is the program files directory for IIS, not the directory where it resides transform.xslt

:

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "An error occurred while loading document 'schema.xsd'. See InnerException for a complete description of the error.",
    "ExceptionType": "System.Xml.Xsl.XslTransformException",
    "StackTrace": "<ommitted>"
    "InnerException": {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Could not find file 'C:\\Program Files (x86)\\IIS Express\\schema.xsd'.",
        "ExceptionType": "System.IO.FileNotFoundException",
        "StackTrace": "<omitted>"
     }
}

      

I don't want to use an absolute path here because I don't want to be overly dependent on the environment the application is deployed to. Is there a way to force the relative source of the path from the same directory that transform.xslt is deployed at runtime?

For reference, the absolute path to the xslt file at runtime:

 C:\\MyFolder\\MyCode\\MyProject\\Web\\bin\\xsl\\transform.xslt

      

EDIT: As requested, below is (roughly) the code that is used to load xslt from the manifest resource stream and perform the transformation. This code is unpacked from several different custom packages to collapse into core libraries, so don't worry about flow control. I promise the real code is much safer:

XmlReader input = this.GetInput();
Stream ouput = new MemoryStream(4096);

Stream stream = typeof(ClassUsingTransform).Assembly.GetManifestResourceStream("transform.xslt");
MemoryStream mStream = new MemoryStream(stream.ToByteArray());
var navigator = new XPathDocument(mStream).CreateNavigator();
XslCompiledTransform processor = new XslCompiledTransform();
processor.Load(navigator, XsltSettings.TrustedXslt, new XmlUrlResolver());
processor.Transform(input, new XsltArgumentList(), output);

      

The XmlUrlResolver cannot be easily unpacked into inline functions, but the type used is inherited from XmlUrlResolver and doesn't seem to change any inline settings. Most of the work on derived classes appears to have focused on performance optimizations. If anyone thinks the implementation is important here, I can try to expand this class a little better.

The XsltArgumentList used was also a derived type, but the argument list is empty as far as I can tell.

+3


source to share





All Articles