.NET 2.0/VS2005Come risolvere XSL in una trasformazione che carica XSL da una stringa?
Sto cercando di utilizzare la classe XslCompiledTransform
per eseguire una trasformazione XSL. Ho due file XSL, il primo dei quali comprende un riferimento all'altro, sotto forma di un <xsl:include>
dichiarazione:
Main.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="Included.xsl" />
...
...
</xsl:stylesheet>
Ora, se potessi caricare il "Main xsl" presentare se stesso come un URI, il mio codice trasformazione sarebbe semplice come:
// 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();
}
il problema è che ricevo il contenuto del file Main.xsl come una stringa e la necessità di caricare la stringa come XmlReader/IXpathNavigable
. Questa è una restrizione necessaria in questo momento. Quando provo a fare lo stesso usando XmlReader/XpathDocument
, fallisce perché il codice cerca "Included.xsl" nella cartella C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\
! Ovviamente, lo XmlResolver
non è in grado di risolvere l'URL relativo perché riceve solo una stringa come input XSL.
miei sforzi in questa direzione sembrano:
// 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();
}
ho cercato di utilizzare il metodo del XmlUrlResolver ResolveUri
per ottenere un Stream
riferimento al file XSL da includere, ma sono confuso su come per usare questo flusso. IOW, come faccio a dire l'oggetto XslCompiledTransform
di utilizzare questo flusso in aggiunta al 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??
Qualsiasi aiuto è molto apprezzato. Ci scusiamo per il lungo post!
Come riferimento, l'eccezione StackTrace assomiglia a questo:
[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
Sto lavorando a qualcosa di simile a ciò che la tua domanda sembra richiedere e ho trovato un articolo di MSDN - [Risolvi lo sconosciuto: Costruire XmlResolvers personalizzati in .NET Framework] (http://msdn.microsoft.com/en-us/ library/aa302284.aspx) - sembra fornire una soluzione molto promettente. –