I have troubles with XmlResolver class. I have a few XSLT files saved in MS SQL database in xml datatype column. I'm trying to write a XmlResolver class implementation, that would load the text from database instead of from the files. But I'm getting XSLT compiler error. Here is very simple example (text of both input and xslt is hardcoded here):
static void Main(string[] args)
{
string xslt = @"<?xml version=""1.0"" encoding=""utf-8""?>
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" exclude-result-prefixes=""msxsl"" >
<xsl:import href=""test.xslt"" />
<xsl:output method=""xml"" indent=""yes""/>
<xsl:template match=""*"">
<xsl:value-of select=""$MyVariable""/>
</xsl:template>
</xsl:stylesheet>";
XDocument transformationInput = XDocument.Parse("<test />");
myResolv res = new myResolv();
XslCompiledTransform transform = new XslCompiledTransform(true)开发者_JS百科;
XsltSettings sett = new XsltSettings(true, true);
StringReader transr = new StringReader(xslt);
XmlReader tranReader = XmlReader.Create(transr);
transform.Load(tranReader, sett, res);
}
}
And here is very simple XmlResolver class:
class myResolv : XmlResolver
{
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
return base.ResolveUri(baseUri, relativeUri);
}
public override System.Net.ICredentials Credentials
{
set { throw new NotImplementedException(); }
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
string fileName = System.IO.Path.GetFileName(absoluteUri.ToString());
if (fileName == "test.xslt")
{
string newXslt = @"<?xml version=""1.0"" encoding=""utf-8""?>
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" exclude-result-prefixes=""msxsl"" >
<xsl:variable name=""MyVariable"" select=""1"" />
</xsl:stylesheet>";
StringReader read = new StringReader(newXslt);
XmlReader xmlread = XmlReader.Create(read);
return xmlread;
}
else
throw new NotImplementedException();
}
}
The execution fails on Transform.Load row (XSLT Compiler Error). When reading the transformation from a file, resolver works fine. But I do not want to read it from a file. Thanks, Petr
The problem is the base-uri that it uses to associate each file (via XmlReader.BaseUri). The fix is fortunately simple; in GetEntity
:
XmlReader xmlread = XmlReader.Create(read, null, fileName);
Note that this means the logical name of the entity (for relative resolution) is now test.xslt
. In your case that is fine, but if the path was using a folder structure you would need to be careful to ensure they are relative/rooted correctly.
精彩评论