的XmlResolver:XSLT编译器错误编译器、错误、XmlResolver、XSLT

2023-09-03 01:38:39 作者:追求梦想是一个很快乐也是一个很艰难的过程,所以我们要不断的激

我有麻烦与的XmlResolver类。我保存在MS SQL数据库中的XML数据类型列几个XSLT文件。我试图写一个的XmlResolver类实现,这将从数据库而不是从文件加载文本。但我发现了XSLT编译器错误。 这是很简单的例子(包括输入和XSLT的文字是硬codeD这里):

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);
        XsltSettings sett = new XsltSettings(true, true);
        StringReader transr = new StringReader(xslt);
        XmlReader tranReader = XmlReader.Create(transr); 
        transform.Load(tranReader, sett, res);
    }
}

这里是很简单的XmlResolver类:

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();
    }
}

执行失败的Transform.Load行(XSLT编译器错误)。当从文件中读取的改造,解析工作正常。但我不希望从文件中读取它。 谢谢, 切赫

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

推荐答案

现在的问题是基URI,它使用每个文件(通过XmlReader.BaseUri)相关联。解决方法是幸运的简单;在 GetEntity

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);

请注意,这意味着实体的逻辑名称(相对分辨率)现在 test.xslt 。你的情况是好的,但如果路径是使用一个文件夹结构,你就必须要小心,以确保它们相对/正确扎根。

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.