如何解决XSL包括从字符串加载XSL转型? [英] How to resolve XSL includes in a Transformation that loads XSL from a String?

查看:270
本文介绍了如何解决XSL包括从字符串加载XSL转型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET 2.0 / VS2005



我试图使用 XslCompiledTransform 类执行XSL转换。我有两个XSL文件,其中第一个包含的形式向其他的参考< XSL:包括> 语句:



Main.xsl:

 <的xsl:样式版本= 1.0的xmlns:XSL =http://www.w3.org/1999/XSL/Transform> 
< XSL:包括HREF =Included.xsl/>
...

< / XSL:样式>

现在,如果我能加载Main.xsl文件本身作为一个URI,我的转换代码就这么简单:

  //这是一个可行的功能。为了演示而已。 
私人字符串变换(串xslFileURI)
{
XslCompiledTransform XSLT =新XslCompiledTransform();

//此负载工作得很好,如果我提供的路径,Main.xsl。
//在xsl:包括自动解决。
xslTransform.Load(xslFileURI);

StringWriter的SW =新的StringWriter();
xslt.Transform(使用Server.Mappath(〜/ XML / input.xml中),空,SW);
返回sw.ToString();
}

的问题是,我收到了Main.xsl文件的内容作为串并需要加载字符串作为的XmlReader / IXpathNavigable 这是在这个时候必要的限制。当我尝试使用做同样的的XmlReader / XPathDocument中,它失败,因为代码的查找Included.xslC:\Program Files\Microsoft的Visual Studio 8\Common7\IDE\ 文件夹!显然,的XmlResolver 不能,因为它只接收一个字符串作为输入XSL来解决相对URL。



我朝这个方向努力的样子:

  //这不工作! HALP! 
私人字符串变换(串xslContents)
{
XslCompiledTransform XSLT =新XslCompiledTransform();
XmlUrlResolver解析器=新XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

//方法1:这种方法是行不通的。
XmlReaderSettings设置=新XmlReaderSettings();
settings.XmlResolver =解析;
的XmlReader xR的= XmlReader.Create(新StringReader(xslContents),设置);
xslt.Load(xR的); //失败

//方法2:不工作的。
XPathDocument的xpDoc =新的XPathDocument(新StringReader(xslContents));
xslt.Load(xpDoc,新XsltSettings(真实的,真实的),旋转变压器); //失败。

StringWriter的SW =新的StringWriter();
xslt.Transform(使用Server.Mappath(〜/ XML / input.xml中),空,SW);
返回sw.ToString();
}



我曾尝试使用 ResolveUri 的XmlUrlResolver的方法来获取引用将包含在XSL文件,但很困惑,如何使用此流。



<$ P:IOW,我怎么告诉 XslCompiledTransform 对象除了Main.xsl的XmlReader使用此流$ p> 乌里mainURI =新的URI(Request.PhysicalApplicationPath +Main.xsl);
乌里URI = resolver.ResolveUri(mainURIIncluded.xsl);

//我可以确认,在以下流的Included.xsl文件加载。
流S = resolver.GetEntity(URI,空的typeof(流))作为流;

//我如何使用此流在上面的功能?





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



有关参考,异常堆栈跟踪看起来是这样的:

  [FileNotFoundException异常:找不到文件'C:\Program Files\Microsoft Visual Studio的8\Common7\IDE\Included.xsl'] 
System.IO .__错误。 WinIOError(的Int32的errorCode,字符串maybeFullPath)328
System.IO.FileStream.Init(字符串路径,模式的FileMode,FileAccess的访问,的Int32权利,布尔useRights,文件共享份额,缓冲区大小的Int32,FileOptions选项,SECURITY_ATTRIBUTES secAttrs,字符串MSGPATH,布尔bFromProxy)1038
System.IO.FileStream..ctor(字符串路径,模式的FileMode,FileAccess的访问,文件共享份额的Int32缓冲区大小)+113
System.Xml.XmlDownloadManager.GetStream(URI URI,ICredentials凭证)+78
System.Xml.XmlUrlResolver.GetEntity(URI绝对URI,字符串的作用,类型ofObjectToReturn)+51
System.Xml.Xsl.Xslt.XsltLoader.CreateReader(URI URI,的XmlResolver的XmlResolver)+22
System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(URI URI,布尔包括)+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,布尔包括)+173


解决方案

嘿地狱犬,
使用自定义XmlUrlResolver

 类MyXmlUrlResolver:XmlUrlResolver 
{
公众覆盖乌里ResolveUri (URI基本URI,串relativeUri)
{
如果(!基本URI = NULL)
返回base.ResolveUri(基本URI,relativeUri);
,否则
返回base.ResolveUri(新的URI(HTTP:// mypath中/),relativeUri);
}
}

和在XslCompiledTransform的装载功能使用它,

 解析器=新MyXmlUrlResolver(); 
xslt.Load(xR的,空,旋转变压器);


.NET 2.0/VS2005

I am trying to use the XslCompiledTransform class to perform a XSL Transformation. I have two XSL files, the first of which includes a reference to the other in the form of an <xsl:include> statement :

Main.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="Included.xsl" />
  ...
  ...
</xsl:stylesheet>

Now, If I could load the "Main.xsl" file itself as a URI, my transformation code would be as simple as :

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

The problem is that I receive the contents of the Main.xsl file as a string and need to load the string as an XmlReader/IXpathNavigable. This is a necessary restriction at this time. When I try to do the same using an XmlReader/XpathDocument, it fails because the code looks for "Included.xsl" in the C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ folder! Obviously, the XmlResolver is not able to resolve the relative URL because it only receives a string as input XSL.

My efforts in this direction look like:

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

I have tried to use the ResolveUri method of the XmlUrlResolver to obtain a Stream referencing the XSL file to be included, but am confused as to how to use this Stream. IOW, how do I tell the XslCompiledTransform object to use this stream in addition to the 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??


Any help is greatly appreciated. Sorry for the long post!

For your reference, the Exception StackTrace looks like this:

[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

解决方案

Hey Cerberus, Use a custom 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);
        }
    }

And use it in load function of XslCompiledTransform,

resolver=new MyXmlUrlResolver();
xslt.Load(xR,null,resolver);

这篇关于如何解决XSL包括从字符串加载XSL转型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆