如何在从String加载XSL的Transformation中解析XSL包含?

Cer*_*rus 6 c# xslt include xslcompiledtransform .net-2.0

.NET 2.0/VS2005

我正在尝试使用XslCompiledTransform该类来执行XSL转换.我有两个XSL文件,第一个包含对<xsl:include>语句形式的引用:

Main.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="Included.xsl" />
  ...
  ...
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

现在,如果我可以将"Main.xsl"文件本身作为URI加载,我的转换代码就像下面这样简单:

// This is a function that works. For demo only.
private string Transform(string xslFileURI)
{
  XslCompiledTransform xslt = new XslCompiledTransform();

  // This load works just fine, if I provide the path to "Main.xsl".
  // The xsl:include is automatically resolved.
  xslTransform.Load(xslFileURI);

  StringWriter sw = new StringWriter();
  xslt.Transform(Server.MapPath("~/XML/input.xml"), null, sw);
  return sw.ToString();
}
Run Code Online (Sandbox Code Playgroud)

问题是我收到Main.xsl文件的内容为字符串,需要加载字符串作为XmlReader/IXpathNavigable.这是此时的必要限制.当我尝试使用a执行相同操作时XmlReader/XpathDocument,它会失败,因为代码在C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\文件夹中查找"Included.xsl" !显然,XmlResolver无法解析相对URL,因为它只接收一个字符串作为输入XSL.

我在这方面的努力看起来像:

// This doesn't work! Halp!
private string Transform(string xslContents)
{
  XslCompiledTransform xslt = new XslCompiledTransform();
  XmlUrlResolver resolver = new XmlUrlResolver();
  resolver.Credentials = CredentialCache.DefaultCredentials;

  //METHOD 1: This method does not work.
  XmlReaderSettings settings = new XmlReaderSettings();
  settings.XmlResolver = resolver;
  XmlReader xR = XmlReader.Create(new StringReader(xslContents), settings);
  xslt.Load(xR);    // fails

  // METHOD 2: Does not work either.
  XPathDocument xpDoc = new XPathDocument(new StringReader(xslContents));
  xslt.Load(xpDoc, new XsltSettings(true, true), resolver);  //fails.

  StringWriter sw = new StringWriter();
  xslt.Transform(Server.MapPath("~/XML/input.xml"), null, sw);
  return sw.ToString();
}
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用ResolveUriXmlUrlResolver 的方法来获取Stream引用要包含的XSL文件,但我对如何使用此Stream感到困惑.IOW,XslCompiledTransform除了Main.xsl XmlReader之外,我如何告诉对象使用此流:

Uri mainURI = new Uri(Request.PhysicalApplicationPath + "Main.xsl");
Uri uri = resolver.ResolveUri(mainURI, "Included.xsl");

// I can verify that the Included.xsl file loads in the Stream below.
Stream s = resolver.GetEntity(uri, null, typeof(Stream)) as Stream;

// How do I use this Stream in the function above??
Run Code Online (Sandbox Code Playgroud)


任何帮助是极大的赞赏.对不起,很长的帖子!

作为参考,Exception StackTrace看起来像这样:

[FileNotFoundException: Could not find file 'C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Included.xsl'.]
   System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +328
   System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) +1038
   System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize) +113
   System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials) +78
   System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn) +51
   System.Xml.Xsl.Xslt.XsltLoader.CreateReader(Uri uri, XmlResolver xmlResolver) +22
   System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(Uri uri, Boolean include) +33
   System.Xml.Xsl.Xslt.XsltLoader.LoadInclude() +349
   System.Xml.Xsl.Xslt.XsltLoader.LoadRealStylesheet() +704
   System.Xml.Xsl.Xslt.XsltLoader.LoadDocument() +293
   System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader, Boolean include) +173
Run Code Online (Sandbox Code Playgroud)

Gee*_*Gee 6

使用自定义XmlUrlResolver

class MyXmlUrlResolver : XmlUrlResolver
    {
        public override Uri ResolveUri(Uri baseUri, string relativeUri)
        {
            if (baseUri != null)
                return base.ResolveUri(baseUri, relativeUri);
            else
                return base.ResolveUri(new Uri("http://mypath/"), relativeUri);
        }
    }
Run Code Online (Sandbox Code Playgroud)

并在XslCompiledTransform的加载函数中使用它,

resolver=new MyXmlUrlResolver();
xslt.Load(xR,null,resolver);
Run Code Online (Sandbox Code Playgroud)


Dav*_*d E 2

我可能错过了显而易见的事情,但是您是否有理由不将 Included.xsl 的 URI 更改为真正的 URL?如果您有权访问,这可以在 XSL 文档中完成,否则可以使用字符串操作?