Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XSL-Übersicht / C#.NET in XSLT aufrufen

C#.NET in XSLT aufrufen

C#.NET in XSLT aufrufen

➪ Auch in C#.NET können Sie XSL-Transformationen durchführen. Zwar ist die Funktionalität des verwendeten Microsoft-Standardprozessors auf XSL 1.0 beschränkt. Daneben gibt es (je nach verwendetem XSL-Prozessor) die Möglichkeit, in XSLT C#.NET-Code zu implementieren und dessen Ergebnisse in den XSLT-Konvertierungsprozess einzubinden.

Auf dieser Seite:

Im folgenden XSL-1.0-Beispiel wird eine C#.NET-Klasse Person implementiert; die set-Properties sind auf value.ToUpper()" gesetzt. In der Methode "public static string getPerson(string VN, string NN)" wird ein Objekt der Klasse Person instanziiert und via Parameterübergabe initialisiert.

Die Klasse Person


<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"	
	xmlns:msxsl="urn:schemas-microsoft-com:xslt"
	xmlns:csharp="http://csharp.org" >
	<xsl:output method="xml" indent="yes"/>

Nun folgt die CDATA-Deklaration der C#.NET-Klasse Person im XSL-Stylesheet.


<msxsl:script 
       language="CSharp" 
       implements-prefix="csharp">
<![CDATA[
  public class Person
  {
    private String _Nachname, _Vorname;
    public String Nachname
    {
      get { return _Nachname; }
      set { _Nachname = value.ToUpper(); }
    }
    public String Vorname
    {
      get { return _Vorname; }
      set { _Vorname = value.ToUpper(); }
    }
    public Person()
    {
    }
    public Person(String vn, String nn)
    {
      this.Nachname = nn;
      this.Vorname = vn;
    }
  }
  public static string getPerson(string VN, string NN)
    {
      Person p = new Person(VN, NN);
      string s = String.Format("{0} {1}", p.Vorname, p.Nachname);
      return s;
    }
]]>
</msxsl:script>

  <xsl:template match="/">
    <root>
      <csharp:person>
        <xsl:value-of select="csharp:getPerson('hugo', 'holzflos')"/>
      </csharp:person>
    </root>
  </xsl:template>
</xsl:stylesheet>

Im template-match-Aufruf wird die Methode


<xsl:value-of select="csharp:getPerson('hugo', 'holzflos')"/>

aufgerufen, von hier stammen auch die übergebenen Werte.

Der Konvertierungsaufruf erfolgt durch ein Objekt der Klasse System.Xml.Xsl.XslCompiledTransform, das das XSL-Stylesheet lädt und dann mit der Transform-Methode die Konvertierung durchführt. Aus Sicherheitsgründen ist noch erforderlich, ein Objekt der Klasse System.Xml.Xsl.XsltSettings mitzugeben, dessen zweiter Parameter enableScript auf true gesetzt werden muss, damit der Aufruf problemlos funktioniert.


static void Main(string[] args)
{
  XsltSettings se = new XsltSettings(true, true);
  XslCompiledTransform t = new XslCompiledTransform();
  t.Load(@"meinstylesheet.xsl", se, null);
  t.Transform(@"input.xml", @"output.xml");
}

Das Ergebnis sieht so aus:


<root xmlns:csharp="http://csharp.org">
  <csharp:person>HUGO HOLZFLOS</csharp:person>
</root>

Selbstverständlich ist auch ein erweiterter Einsatz möglich, wo der Input direkt aus dem XML-Dokument kommt.


<xsl:template match="/">
 <root>
  <xsl:for-each 
       select="/Orte/Ort[1]/Mensch">
   <csharp:person>
    <xsl:value-of 
         select="csharp:getPerson(vorname, name)"/>
   </csharp:person>
  </xsl:for-each>
 </root>
</xsl:template>

Das Ergebnis dieses Aufrufs finden Sie hier:


<root xmlns:csharp="http://csharp.org">
 <csharp:person>HUGO HOLZFLOS</csharp:person>
 <csharp:person>NICOLE NIXLOS</csharp:person>
 <csharp:person>STEFAN SPRACHLOS</csharp:person>
 <csharp:person>STEFAN SAGBLOS</csharp:person>
 <csharp:person>SIGGI SORGLOS</csharp:person>
 <csharp:person>HEINI HERZLOS</csharp:person>
</root>

Wie erwähnt, ist der Aufruf abhängig vom eingesetzten XSL-Prozessor. Das kann auch schiefgehen, wie sich beim Einsatz von XProc/calabash zeigte:


ERROR: XPST0017:Cannot find a matching 
2-argument function named {http://csharp.org}getPerson()

XSL-Transformation mit XslCompiledTransform

Die wohl einfachste Form der XSL-Transformation mit C#.NET ist diese:


XslCompiledTransform t = new XslCompiledTransform();
t.Load(@"meinstylesheet.xslt");
t.Transform(@"input.xml", @"output.html");

Eventuell kommen Sie nicht umhin, das XSL_Stylesheet über einen XmlReader zu laden und hierbei entsprechende XmlReaderSettings und XsltSettings zu deklarieren. Auch kann es erforderlich sein, die tatsächliche XSL-Transformation über einen XPathNavigator und einen XmlWriter durchzuführen.


XslCompiledTransform t = new XslCompiledTransform();
t.Load(XmlReader.Create(@"meinstylesheet.xslt",
    new XmlReaderSettings()
    {
     DtdProcessing = DtdProcessing.Parse
    }),
    new XsltSettings(true, false),
    null
   );
XmlDocument tmpdoc = new XmlDocument();
tmpdoc.Load(@"input.xml");
var nav = tmpdoc.CreateNavigator();
XmlReader xinput = XmlReader.Create(@"output.xml",
    new XmlReaderSettings()
    {
     DtdProcessing = DtdProcessing.Parse
    });
using (var myWriter = System.Xml.XmlWriter.Create(@"output.xml"))
   {
    t.Transform(xinput, myWriter);
   }

Eine Alternative mit TextWriter:


XslCompiledTransform t = new XslCompiledTransform();
t.Load(XmlReader.Create(@"meinstylesheet.xslt",
        new XmlReaderSettings()
        {
           DtdProcessing = DtdProcessing.Parse
        }),
        new XsltSettings(true, false),
        null
);
XmlDocument tmpdoc = new XmlDocument();
tmpdoc.Load(@"input.xml");
XPathNavigator nav = tmpdoc.CreateNavigator();
using (TextWriter myWriter = File.CreateText(@"output.txt"))
{
        t.Transform(nav, null, myWriter);
}

Noch eine Alternative ohne XPathNavigator:


XslCompiledTransform t = new XslCompiledTransform();
t.Load(XmlReader.Create(@"meinstylesheet.xslt",
    new XmlReaderSettings()
    {
        DtdProcessing = DtdProcessing.Parse
    }),
    new XsltSettings(true, false),
    null
);
XmlReader xinput = XmlReader.Create(@"input.xml",
    new XmlReaderSettings()
    {
        DtdProcessing = DtdProcessing.Parse
    });
using (var myWriter = System.Xml.XmlWriter.Create(@"output.xml"))
{
    t.Transform(xinput, myWriter);
}

wg / 24. Dezember 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/Csharp_in_XSL.html