Blocs de scripts utilisant msxsl:script

Notes

Les blocs de script sont pris en charge uniquement dans .NET Framework. Ils ne sont pas pris en charge sur .NET Core ou .NET 5 ou des versions ultérieures.

La classe XslCompiledTransform prend en charge les scripts incorporés en utilisant l'élément msxsl:script. Quand la feuille de style est chargée, les fonctions définies sont compilées en langage CIL (Common Intermediate Language) par le CodeDOM (Code Document Object Model) et sont exécutées au moment de l’exécution. L' assembly généré à partir du bloc de script incorporé est distinct de l'assembly généré pour la feuille de style.

Activer les scripts XSLT

La prise en charge des scripts incorporés est un réglage XSLT facultatif de la classe XslCompiledTransform. La prise en charge des scripts est désactivée par défaut. Pour l'activer, créez un objet XsltSettings avec la propriété EnableScript définie sur true et transmettez l'objet à la méthode Load.

Notes

Le script XSLT ne doit être activé que si la prise en charge des scripts est nécessaire et si vous travaillez dans un environnement totalement fiable.

Définition de l'élément msxsl:script

L’élément msxsl:script est une extension Microsoft de la recommandation XSLT 1.0. Il se définit comme suit :

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

Le préfixe msxsl est lié à l'URI d'espace de noms urn:schemas-microsoft-com:xslt. La feuille de style doit inclure la déclaration d'espace de noms xmlns:msxsl=urn:schemas-microsoft-com:xslt.

L'attribut language est facultatif. Sa valeur est le langage du bloc de code incorporé. Ce langage est mappé au compilateur CodeDOM approprié à l’aide de la méthode CodeDomProvider.CreateProvider. La classe XslCompiledTransform peut prendre en charge tout langage Microsoft .NET, à condition que le fournisseur approprié soit installé sur l'ordinateur et enregistré dans la section system.codedom du fichier machine.config. Si aucun attribut language n'est spécifié, le langage par défaut est JScript. Le nom du langage ne respecte pas la casse : les termes « JavaScript » et « javascript » sont équivalents.

L'attribut implements-prefix est obligatoire. Cet attribut est utilisé pour déclarer un espace de noms et l'associer au bloc de script. La valeur de cet attribut est le préfixe qui représente l'espace de noms. Ce préfixe peut être défini à un endroit d'une feuille de style.

Notes

Lors de l'utilisation de l'élément msxsl:script, il est vivement recommandé de placer le script (quel que soit son langage) dans une section CDATA. Étant donné que le script peut contenir des opérateurs, identificateurs ou délimiteurs pour un langage donné, s'il n'est pas contenu dans une section CDATA, il risque d'être interprété à tort comme du XML. Le XML suivant illustre un modèle de la section CDATA où peut être placé le code.

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

Fonctions de script

Les fonctions peuvent être déclarées dans l'élément msxsl:script. Lorsqu'une fonction est déclarée, elle est contenue dans un bloc de script. Les feuilles de style peuvent contenir plusieurs blocs de scripts, chacun fonctionnant indépendamment des autres. Ainsi, si vous êtes en cours d'exécution dans un bloc de script, vous ne pouvez pas appeler une fonction que vous avez définie dans un autre bloc de script, sauf si elle est déclarée comme possédant le même espace de noms et le même langage de script. Puisque chaque bloc de script peut être écrit dans son propre langage et que le bloc est analysé en fonction des règles grammaticales de cet analyseur de langage, il est recommandé d'utiliser la syntaxe correcte pour le langage utilisé. Par exemple, si vous êtes dans un bloc de script Microsoft C#, utilisez la syntaxe de commentaires C#.

Les arguments fournis et les valeurs retournées par la fonction peuvent être de n’importe quel type. Les types XPath W3C étant un sous-ensemble des types CLR (common language runtime), une conversion de type est appliquée aux types qui ne sont pas considérés comme des types XPath. Le tableau suivant indique les correspondances entre les types W3C et les types CLR.

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

Les types CLR numériques sont convertis en objet Double. Le type DateTime est converti en String. Les types IXPathNavigable sont convertis en XPathNavigator. XPathNavigator[] est converti en objet XPathNodeIterator.

Tous les autres types provoquent une erreur.

Importation d'espaces de noms et d'assemblys

La classe XslCompiledTransform prédéfinit un ensemble d'assemblys et d'espaces de noms qui sont pris en charge par défaut par l'élément msxsl:script. Cependant, vous pouvez utiliser des classes et des membres appartenant à un espace de noms qui ne figure pas sur la liste prédéfinie en important l'assembly et l'espace de noms dans un bloc msxsl:script.

Assemblys

Les deux assemblys suivants sont référencés par défaut :

  • System.dll

  • System.Xml.dll

  • Microsoft.VisualBasic.dll (lorsque le langage de script est VB)

Vous pouvez importer les assemblys supplémentaires en utilisant l'élément msxsl:assembly. Cela comprend l'assembly lorsque la feuille de style est compilée. L'élément msxsl:assembly a la définition suivante :

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

L'attribut name contient le nom de l'assembly et l'attribut href contient le chemin de l'assembly. Le nom de l'assembly peut être un nom complet, comme « System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 », ou un nom court, comme « System.Web ».

Espaces de noms

Les espaces de noms suivants sont inclus par défaut :

  • Système

  • System.Collection

  • System.Text

  • System.Text.RegularExpressions

  • System.Xml

  • System.Xml.Xsl

  • System.Xml.XPath

  • Microsoft.VisualBasic (lorsque le langage de script est VB)

Vous pouvez ajouter la prise en charge d'autres espaces de noms à l'aide de l'attribut namespace. La valeur de l'attribut est le nom de l'espace de noms.

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

Exemple

L'exemple suivant utilise un script incorporé pour calculer la circonférence d'un cercle en fonction de son rayon.

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>

Sortie

<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>

Voir aussi