Skriptblöcke, die "msxsl:script" verwenden

Hinweis

Skriptblöcke werden nur im .NET Framework unterstützt. In .NET Core oder .NET 5 oder höher werden sie nicht unterstützt.

Die XslCompiledTransform-Klasse unterstützt eingebettete Skripts unter Verwendung des msxsl:script-Elements. Beim Laden des Stylesheets werden alle definierten Funktionen von CodeDOM (Code Document Object Model) in CIL (Common Intermediate Language) kompiliert und zur Laufzeit ausgeführt. Die aus dem eingebetteten Skriptblock generierte Assembly und die für das Stylesheet generierte Assembly sind voneinander verschieden.

Aktivieren von XSLT-Skript

Die Unterstützung für eingebettete Skripts ist eine optionale XSLT-Einstellung für die XslCompiledTransform-Klasse. Die Skriptunterstützung ist in der Standardeinstellung deaktiviert. Sie können die Skriptunterstützung aktivieren, indem Sie ein XsltSettings-Objekt erstellen, bei dem die EnableScript-Eigenschaft auf true festgelegt wurde, und das Objekt an die Load-Methode übergeben.

Hinweis

XSLT-Skripts sollten nur aktiviert werden, wenn eine Skriptunterstützung erforderlich ist und Sie mit einer vollständig vertrauenswürdigen Umgebung arbeiten.

Elementdefinition von "msxsl:script"

Das msxsl:script-Element ist eine Microsoft-Erweiterung der XSLT 1.0-Empfehlung und weist folgende Definition auf:

<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>

Das msxsl-Präfix ist an den urn:schemas-microsoft-com:xslt-Namespace-URI gebunden. Das Stylesheet muss die xmlns:msxsl=urn:schemas-microsoft-com:xslt-Namespacedeklaration enthalten.

Das language-Attribut ist optional. Sein Wert entspricht der Codesprache des eingebetteten Codeblocks. Die Sprache wird mithilfe der CodeDomProvider.CreateProvider-Methode dem entsprechenden CodeDOM-Compiler zugeordnet. Die XslCompiledTransform-Klasse unterstützt alle Microsoft .NET-Sprachen, vorausgesetzt, der entsprechende Anbieter ist auf dem Computer installiert und im Abschnitt "system.codedom" der Datei "machine.config" registriert. Wenn kein language-Attribut angegeben ist, wird die Standardsprache JScript verwendet. Beim Namen der Sprache wird die Groß- und Kleinschreibung nicht berücksichtigt, daher sind "JavaScript" und "javascript" identisch.

Das implements-prefix-Attribut ist erforderlich. Mit diesem Attribut wird ein Namespace deklariert und mit dem Skriptblock verknüpft. Der Wert dieses Attributs ist das Präfix, das den Namespace darstellt. Dieses Präfix kann an einer beliebigen Stelle im Stylesheet definiert werden.

Hinweis

Bei Verwendung des msxsl:script-Elements wird dringend empfohlen, das Skript ungeachtet der verwendeten Sprache in einem CDATA-Abschnitt zu platzieren. Da das Skript Operatoren, Bezeichner oder Trennzeichen für eine bestimmte Sprache enthalten kann, wenn es nicht in einem CDATA-Abschnitt enthalten ist, kann es möglicherweise als XML fehlinterpretiert werden. Der folgende XML-Code zeigt eine Vorlage des CDATA-Abschnitts, in dem Code platziert werden kann.

<msxsl:script implements-prefix='your-prefix' language='CSharp'>
<![CDATA[
// Code block.
]]>
</msxsl:script>

Skriptfunktionen

Funktionen können innerhalb des msxsl:script-Elements deklariert werden. Wenn eine Funktion deklariert wurde, ist sie in einem Skriptblock enthalten. Stylesheets können mehrere voneinander unabhängige Skriptblöcke enthalten. Sie können daher bei der Ausführung innerhalb eines Skriptblocks nur dann eine Funktion aufrufen, die Sie in einem anderen Skriptblock definiert haben, wenn diese Funktion so deklariert wurde, dass sie den gleichen Namespace und die gleiche Skriptsprache verwendet. Da jeder Skriptblock in einer eigenen Sprache vorliegen kann und der Block gemäß der Grammatikregeln für den betreffenden Sprachparser analysiert wird, wird empfohlen, die korrekte Syntax für die verwendete Sprache einzuhalten. Verwenden Sie z. B. in einem Microsoft C#-Skriptblock die Kommentarsyntax von C#.

Die bereitgestellten Argumente und Rückgabewerte für die Funktion können einen beliebigen Typ aufweisen. Da die XPath-Typen des W3C eine Teilmenge der CLR-Typen (Common Language Runtime) sind, findet die Typkonvertierung für Typen statt, die nicht als XPath-Typen betrachtet werden. In der folgenden Tabelle werden die entsprechenden W3C-Typen und die äquivalenten CLR-Typen aufgelistet.

W3C-Typ CLR-Typ
String String
Boolean Boolean
Number Double
Result Tree Fragment XPathNavigator
Node Set XPathNodeIterator

Numerische CLR-Typen werden in Double konvertiert. Der DateTime-Typ wird in String konvertiert. IXPathNavigable-Typen werden in XPathNavigator konvertiert. XPathNavigator[] wird in XPathNodeIterator konvertiert.

Alle anderen Typen lösen einen Fehler aus.

Importieren von Namespaces und Assemblys

Die XslCompiledTransform-Klasse definiert eine Gruppe von Assemblys und Namespaces vor, die in der Standardeinstellung vom msxsl:script-Element unterstützt werden. Sie können jedoch Klassen und Member verwenden, die zu einem Namespace gehören, der nicht in der vordefinierten Liste aufgeführt ist, indem Sie die Assembly und den Namespace in den msxsl:script-Block importieren.

Assemblys

In der Standardeinstellung wird auf die folgenden zwei Assemblys verwiesen:

  • System.dll

  • System.Xml.dll

  • Microsoft.VisualBasic.dll (bei Skriptsprache VB)

Mithilfe des msxsl:assembly-Elements können Sie die zusätzlichen Assemblys importieren. Dies gilt auch für die Assembly beim Kompilieren des Stylesheets. Das msxsl:assembly-Element weist folgende Definition auf:

<msxsl:script>
  <msxsl:assembly name="system.assemblyName" />
  <msxsl:assembly href="path-name" />
    <![CDATA[
    // User code
    ]]>
</msxsl:script>

Das name-Attribut enthält den Namen der Assembly, und das href-Attribut enthält den Pfad der Assembly. Der Assemblyname kann ein vollständiger Name sein, z. B. "System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", oder ein Kurzname wie "System.Web".

Namespaces

In der Standardeinstellung sind die folgenden Namespaces enthalten:

  • System

  • System.Collection

  • System.Text

  • System.Text.RegularExpressions

  • System.Xml

  • System.Xml.Xsl

  • System.Xml.XPath

  • Microsoft.VisualBasic (bei Skriptsprache VB)

Mithilfe des namespace-Attributs können Sie Unterstützung für zusätzliche Namespaces hinzufügen. Der Attributwert ist der Name des Namespaces.

<msxsl:script>
  <msxsl:using namespace="system.namespaceName" />
    <![CDATA[
    // User code
    ]]>
</msxsl:script>

Beispiel

Im folgenden Beispiel wird der Umfang eines Kreises bei angegebenem Radius unter Verwendung eines eingebetteten Skripts berechnet.

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

public class Sample {

  private const String filename = "number.xml";
  private const String stylesheet = "calc.xsl";

  public static void Main() {

    // Compile the style sheet.
    XsltSettings xslt_settings = new XsltSettings();
    xslt_settings.EnableScript = true;
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(stylesheet, xslt_settings, new XmlUrlResolver());

    // Load the XML source file.
    XPathDocument doc = new XPathDocument(filename);

    // Create an XmlWriter.
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    settings.Indent = true;
    XmlWriter writer = XmlWriter.Create("output.xml", settings);

    // Execute the transformation.
    xslt.Transform(doc, writer);
    writer.Close();
  }
}
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports System.Xml.Xsl

Public class Sample

    Private Const filename As String = "number.xml"
    Private Const stylesheet As String = "calc.xsl"

    Public Shared Sub Main()

        ' Compile the style sheet.
        Dim xslt_settings As XsltSettings = New XsltSettings()
        xslt_settings.EnableScript = true
        Dim xslt As XslCompiledTransform = New XslCompiledTransform()
        xslt.Load(stylesheet, xslt_settings, New XmlUrlResolver())

        ' Load the XML source file.
        Dim doc As XPathDocument = New XPathDocument(filename)

        ' Create an XmlWriter.
        Dim settings As XmlWriterSettings = New XmlWriterSettings()
        settings.OmitXmlDeclaration = true
        settings.Indent = true
        Dim writer As XmlWriter = XmlWriter.Create("output.xml", settings)

        ' Execute the transformation.
        xslt.Transform(doc, writer)
        writer.Close()
    End Sub
End Class

number.xml

<?xml version='1.0'?>
<data>
  <circle>
    <radius>12</radius>
  </circle>
  <circle>
    <radius>37.5</radius>
  </circle>
</data>

calc.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:user="urn:my-scripts">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
  public double circumference(double radius){
    double pi = 3.14;
    double circ = pi*radius*2;
    return circ;
  }
  ]]>
  </msxsl:script>
  <xsl:template match="data">
    <circles>
      <xsl:for-each select="circle">
        <circle>
          <xsl:copy-of select="node()"/>
          <circumference>
            <xsl:value-of select="user:circumference(radius)"/>
          </circumference>
        </circle>
      </xsl:for-each>
    </circles>
  </xsl:template>
</xsl:stylesheet>

Output

<circles xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
  <circle>
    <radius>12</radius>
    <circumference>75.36</circumference>
  </circle>
  <circle>
    <radius>37.5</radius>
    <circumference>235.5</circumference>
  </circle>
</circles>

Siehe auch