/// Thursday, April 13
XslTransform and xsl:document() woes
This little .NET feature consumed half my day (sarcasm intended). XslTransformation and document(''). .NET XSL transformations may behave unexpectedly when a stylesheet invokes the xsl:document() function. The same stylesheet results in two different outputs. If the stylesheet is loaded from a URI, such as a file, transformations produce expected results. Loading the stylesheet from a stream or a string, however, requires the workaround as described in the article above.
Why would one opt to load a stylesheet from a Stream or string? I prefer to embed test files and test stylesheets into an assembly by selecting the Embedded Resource action in Visual Studio. This is a neat trick if building with both NAnt and Visual Studio. Most NAnt projects build assemblies into a build, dist or bin directory. Visual Studio defaults to bin\debug and bin\release. An embedded resource always has the same path regardless where your assembly is located.
Loading a stylesheet from a non-URI location may reduce I/O as hinted in the article above. XSLT is ubiquitous. As sectors move towards standardization stylesheets become larger and larger. Most developers laboriously map one element to another. I treat XSLT as a cool programming language with a funky syntax. XML is structured and soon a resourceful developer realizes there's a pattern to the transformation. I tend to use lookup tables with the xsl:document() function. Resolving document('') to memory instead of a file reduces I/O.
I created a utility function to load stylesheets that use xsl:document().
XmlReader stylesheet = XmlUtils.LoadNonUriStylesheet(IOUtils.OpenEmbeddedResource("res/test.xls"));
LoadNonUriStylesheet loads the stylesheet assigning it an arbitrary URI. The URI is resolved by a custom resolver during transformation. OpenEmbeddedResource converts the res/test.xls path to a fully qualified namespace path then opens a Stream for the resource.