.NET 2.0/VS2005¿Cómo resolver XSL incluye en una Transformación que carga XSL desde una Cadena?
Estoy tratando de utilizar la clase XslCompiledTransform
para realizar una transformación XSL. Tengo dos archivos XSL, el primero de los cuales incluye una referencia a la otra en forma de una declaración <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>
Ahora, si pudiera cargar el "Principal .xsl" presentar a sí mismo como un URI, mi código de transformación sería tan simple como:
// 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();
}
el problema es que yo reciba el contenido del archivo Main.xsl como una cadena y la necesidad de cargar la cadena como una XmlReader/IXpathNavigable
. Esta es una restricción necesaria en este momento. Cuando intento hacer lo mismo con un XmlReader/XpathDocument
, falla porque el código busca "Included.xsl" en la carpeta C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\
! Obviamente, el XmlResolver
no puede resolver la URL relativa porque solo recibe una cadena como entrada XSL.
Mis esfuerzos en este sentido se parecen:
// 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();
}
He intentado utilizar el método de la XmlUrlResolver ResolveUri
para obtener un Stream
referencia al archivo XSL para ser incluidos, pero estoy confundido en cuanto a cómo para usar esta corriente OIA, ¿cómo le digo el objeto XslCompiledTransform
utilizar esta corriente, además de la 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??
Cualquier ayuda es muy apreciada. Perdón por la larga publicación!
Para su referencia, la excepción StackTrace se parece a esto:
[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
Estoy trabajando en algo similar a lo que su pregunta parece requerir y encontré un artículo de MSDN - [Resolviendo lo Desconocido: creando XmlResolvers personalizados en .NET Framework] (http://msdn.microsoft.com/en-us/ library/aa302284.aspx) - que parece proporcionar una solución muy prometedora. –