recursos name leer generate example comentarios archivo agregar c# xml xslt

name - xml comments c#



¿Cómo transformar XML como una cadena sin usar archivos en.NET? (7)

Digamos que tengo dos cadenas:

  • uno es datos XML
  • y el otro es datos XSL.

Los datos xml y xsl se almacenan en columnas de la base de datos, si es necesario.

¿Cómo puedo transformar el XML en C # sin guardar primero los archivos xml y xsl como archivos? Me gustaría que la salida sea también una cadena (HTML de la transformación).

Parece que C # prefiere transformarse a través de archivos. No pude encontrar una sobrecarga de entrada de cadena para Load () en XslCompiledTransform. Entonces, es por eso que estoy preguntando.


Envío el contenido xml y luego cargo el documento XSLT, aplique la transformación y luego devuelva el nuevo xml.

public static string Transform(string xmlString) { string output = String.Empty; try { // Load an XML string into the XPathDocument. StringReader rdr = new StringReader(xmlString); XPathDocument myXPathDoc = new XPathDocument(rdr); var myXslTrans = new XslTransform(); //load the Xsl myXslTrans.Load("XSLTFile.xslt"); //create the output stream StringWriter sw = new StringWriter(); XmlWriter xwo = XmlWriter.Create(sw); //do the actual transform of Xml myXslTrans.Transform(myXPathDoc, null, xwo); output = sw.ToString(); xwo.Close(); return output; } catch (Exception e) { Console.WriteLine("Exception: {0}", e.ToString()); throw; } }

NOTA: "XSLTFile.xslt" Se agrega a la solución y establece la propiedad "Copiar en el directorio de salida" en "Copiar siempre".


Esto es lo que hice. Es una combinación de tus respuestas. Voté las respuestas que inspiraron esto:

string output = String.Empty; using (StringReader srt = new StringReader(xslInput)) // xslInput is a string that contains xsl using (StringReader sri = new StringReader(xmlInput)) // xmlInput is a string that contains xml { using (XmlReader xrt = XmlReader.Create(srt)) using (XmlReader xri = XmlReader.Create(sri)) { XslCompiledTransform xslt = new XslCompiledTransform(); xslt.Load(xrt); using (StringWriter sw = new StringWriter()) using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML { xslt.Transform(xri, xwo); output = sw.ToString(); } } }

Nota: esta declaración es obligatoria en xsl, para que salga como HTML:

<xsl:output method="html" omit-xml-declaration="yes" />


Me tomó mucho tiempo (literalmente años) averiguar qué tan conciso es el código usando Stream y / o TextWriter si usa los modismos adecuados.

Suponiendo que la transform y la input son cadenas:

StringWriter sw = new StringWriter(); using (XmlReader xrt = XmlReader.Create(new StringReader(transform)) using (XmlReader xri = XmlReader.Create(new StringReader(input)) using (XmlWriter xwo = XmlWriter.Create(sw)) { XslCompiledTransform xslt = new XslCompiledTransform(); xslt.Load(xrt); xslt.Transform(xri, xwo); } string output = sw.ToString();



Una versión de VB.Net inspirada en la respuesta de Robert Rossney:

Private Function TransformXML(XMLPath As String, XSLPath As String) As String Dim XSLT As XslCompiledTransform = New XslCompiledTransform() Dim sWriter As StringWriter = New StringWriter Dim xReader As XmlReader = XmlReader.Create(XMLPath) Using xWriter As XmlWriter = XmlWriter.Create(sWriter) XSLT.Load(XSLPath) XSLT.Transform(xReader, xWriter) End Using Return sWriter.ToString End Function


Utilizaría las XmlReader.Create(DatabaseBlobStream) y XmlWriter.Create(StringBuilder) . Usando el siguiente objeto DatabaseBlobStream

DatabaseBlobStream.cs

internal class DatabaseBlobStream : Stream { private readonly IDataReader reader; private readonly int columnIndex; private long streamPosition; internal DatabaseBlobStream(IDataReader reader, int columnIndex) { this.reader = reader; this.columnIndex = columnIndex; } public override bool CanRead { get { return reader.GetFieldType(columnIndex) == typeof (byte[]) && !reader.IsDBNull(columnIndex); } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return false; } } public override void Flush() { throw new Exception("This stream does not support writing."); } public override long Length { get { throw new Exception("This stream does not support the Length property."); } } public override long Position { get { return streamPosition; } set { streamPosition = value; } } public override int Read(byte[] buffer, int offset, int count) { if (reader.IsDBNull(columnIndex)) return 0; int bytesRead = (int)reader.GetBytes(columnIndex, streamPosition + offset, buffer, 0, count); streamPosition += bytesRead; return bytesRead; } public override long Seek(long offset, SeekOrigin origin) { throw new Exception("This stream does not support seeking."); } public override void SetLength(long value) { throw new Exception("This stream does not support setting the Length."); } public override void Write(byte[] buffer, int offset, int count) { throw new Exception("This stream does not support writing."); } public override void Close() { try { reader.Close(); } finally { base.Close(); } } protected override void Dispose(bool disposing) { try { reader.Dispose(); } finally { base.Dispose(disposing); } } }


editar: usando-bloques agregados

// input-xml string xmlinput = String.Empty; // xslt string xsltinput = String.Empty; // output-xml string xmloutput = String.Empty; // Prepare input-xml XPathDocument doc = new XPathDocument(new StringReader(xmlinput)); // Prepare XSLT XslTransform xslt = new XslTransform(); // Creates a XmlReader from your xsl string using (XmlReader xmlreader = XmlReader.Create(new StringReader(xsltinput))) { //Load the stylesheet. xslt.Load(xmlreader); // transform using (StringWriter sw = new StringWriter()) { xslt.Transform(doc, null, sw); // save to string xmloutput = sw.ToString(); } }