views:

210

answers:

1

There are two XSL files. One includes another using an <xsl:include>. The main template desides which actual templates to call depending on node values, and included templates contain actual transformation rules. Nothing special here.

But included file has a script block:

  <msxsl:script language="VB" implements-prefix="user">
    <msxsl:assembly href="C:\Absolute\Path\MyEscaper.dll" />
    <msxsl:using namespace="ZebraEscaper.MyCompany" />
    <![CDATA[
    Public Function escape(s As String) As String
      Return EncodeField(s, True)
    End Function
    ]]>
  </msxsl:script>

The user:escape() function is later used in the included template.

Now, I go to VS2008 XSLT debugger.

The main template calls <xsl:apply-templates> and the included template executes. And a FileNotFound exception occurs, "Could not load file or assembly 'MyEscaper', Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."

Now, if I go to just the included file and execute it as if it was a standalone template, not included into anything, everything works. The assembly gets found and the function gets called, but obviously results don't make sence as the template designed to be an inclusion.

So the question -- why can't the system find the assembly when the template is included?

More information

Documentation states that "The assembly path name is resolved twice - once during compilation and once during execution." If I intentionally make a typo in the path, I get same FileNotFound exception, but formatted differently, where the system says it cannot find file://C:\Absolute\Path\MyEscaper.dll. However, when the path is correct, the exception claims it couldn't find MyEscaper.dll, version=blabla, public token=null, and that exception occurs in CompiledStylesheet.dll created by .Net. I believe that the compiled stylesheet is told to call the assembly by name, not by href, and since it's not in its temporary folder, the call fails.

Why so? Where and why does an absolute path get translated (wrongly) into a relative one, and how do I control it?

A: 

So.

For some reason, in an included scenario path to the assembly is resolved differently during compilation and during execution. Why it is so, I haven't got a clue.

Only two sane solutions were found:

  1. Move all code from the referenced assembly into the XSL template, making it an embedded script. In case of small helper functions that is actually preferred. Otherwise,

  2. Sing the referenced assembly with a strong name, add it to the GAC, and refer to it from templates using name, not href. This way the assembly will be looked up in the same way during compilation and execution, and will be found.

GSerg