2010-03-30 2 views
8

Ich habe eine Funktion, die 2 Parameter dauert: 1 = XML-Datei, 2 = XSLT-Datei, führt dann eine Umwandlung durch und gibt das resultierende HTML zurück. HierC# Wie führe ich eine Live-XSLT-Transformation für ein In-Memory-Objekt durch?

ist die Funktion:

/// <summary> 
/// Will apply an XSLT style to any XML file and return the rendered HTML. 
/// </summary> 
/// <param name="xmlFileName"> 
/// The file name of the XML document. 
/// </param> 
/// <param name="xslFileName"> 
/// The file name of the XSL document. 
/// </param> 
/// <returns> 
/// The rendered HTML. 
/// </returns> 
public string TransformXml(string xmlFileName, string xslFileName) 
{ 
    var xtr = new XmlTextReader(xmlFileName) 
        { 
         WhitespaceHandling = WhitespaceHandling.None 
        }; 
    var xd = new XmlDocument(); 
    xd.Load(xtr); 

    var xslt = new System.Xml.Xsl.XslCompiledTransform(); 
    xslt.Load(xslFileName); 
    var stm = new MemoryStream(); 
    xslt.Transform(xd, null, stm); 
    stm.Position = 1; 
    var sr = new StreamReader(stm); 
    xtr.Close(); 
    return sr.ReadToEnd(); 
} 

Ich mag die Funktion nicht ändern, eine Datei für die XML zu akzeptieren, sondern nur ein Objekt. Das Objekt ist genau mit dem XSLT kompatibel, wenn es in Datei serialisiert wurde. Aber ich möchte es nicht zuerst in eine Datei serialisieren müssen.

Also zusammenfassend: Behalte das xslt aus einer Datei, aber die XML-Eingabe sollte ein Objekt, das ich übergeben und möchte das XML aus ohne Dateisysteminteraktion generieren.

Antwort

9

Sie können das Objekt in eine Zeichenfolge serialisieren, die Zeichenfolge in eine XmlDocument laden und die Umwandlung durchführen:

public string TransformXml(object data, string xslFileName) 
{ 

    XmlSerializer xs = new XmlSerializer(data.GetType()); 
    string xmlString; 
    using (StringWriter swr = new StringWriter()) 
    { 
     xs.Serialize(swr, data); 
     xmlString = swr.ToString(); 
    } 

    var xd = new XmlDocument(); 
    xd.LoadXml(xmlString); 

    var xslt = new System.Xml.Xsl.XslCompiledTransform(); 
    xslt.Load(xslFileName); 
    var stm = new MemoryStream(); 
    xslt.Transform(xd, null, stm); 
    stm.Position = 0; 
    var sr = new StreamReader(stm); 
    return sr.ReadToEnd(); 
} 
+1

Ich habe das gerade benutzt, muss aber darauf hinweisen, dass ich 'Position' in' = 0' ändern musste . Ansonsten hat es wie erwartet funktioniert. =) – Dracorat

3

Hier ist eine Funktion, die ein Objekt in ein XDocument verwandelt (Sie können es für XmlDocument ändern, wenn Sie XDocument noch nicht verwenden). Natürlich werden Ausnahmen ausgelöst, wenn das Objekt nicht serialisiert werden kann.

public static XDocument ConvertToXml<T>(this T o) 
{ 
    StringBuilder builder = new StringBuilder(); 
    StringWriter writer = new StringWriter(builder); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    serializer.Serialize(writer,o); 
    StringReader reader = new StringReader(builder.ToString()); 
    return XDocument.Load(reader); 
} 

und hier ist das für XmlDocument

public static XmlDocument ConvertToXml<T>(this T o) 
{ 
    StringBuilder builder = new StringBuilder(); 
    StringWriter writer = new StringWriter(builder); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    serializer.Serialize(writer,o); 
    StringReader reader = new StringReader(builder.ToString()); 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(reader); 
    return doc; 
} 
+0

XslCompiledTransform benötigt ein XmlDocument, kein XDocument ... Ansonsten ist das ungefähr meine Idee;) –

1

Nicht getestet, aber Sie können die XPathDocument verwenden, um einen Strom zu nehmen, und da XPathDocument IXPathNavigable implementiert, kann es für Transformationen verwendet werden:

public string TransformXml(Stream xmlFile, string xslFileName) 
{ 
     var doc = new XPathDocument(xmlFile); 
     var xslt = new System.Xml.Xsl.XslCompiledTransform(); 
     xslt.Load(xslFileName); 
     var stm = new MemoryStream(); 
     xslt.Transform(doc, null, stm); 
     stm.Position = 1; 
     var sr = new StreamReader(stm); 
     return sr.ReadToEnd(); 
    } 
0

einen Blick auf this article nehmen, die eine XPathNavigator beschreibt schaffen, die die Eigenschaften eines Objektgraphen navigieren können, die eine ziemlich starke Kombination von XPath und XSLT ist.

Verwandte Themen