Bloki skryptów i element msxsl:script

Uwaga

Bloki skryptów są obsługiwane tylko w programie .NET Framework. Nieone obsługiwane na platformie .NET Core lub .NET 5 lub nowszym.

Klasa XslCompiledTransform obsługuje skrypty osadzone przy użyciu msxsl:script elementu . Po załadowaniu arkusza stylów wszystkie zdefiniowane funkcje są kompilowane do wspólnego języka pośredniego (CIL) przez model code Document Object Model (CodeDOM) i są wykonywane w czasie wykonywania. Zestaw wygenerowany na podstawie bloku osadzonego skryptu jest oddzielony od zestawu wygenerowanego dla arkusza stylów.

Włączanie skryptu XSLT

Obsługa skryptów osadzonych jest opcjonalnym ustawieniem XSLT w XslCompiledTransform klasie. Obsługa skryptów jest domyślnie wyłączona. Aby włączyć obsługę skryptów, utwórz XsltSettings obiekt z właściwością EnableScript ustawioną na true i przekaż obiekt do Load metody .

Uwaga

Skrypty XSLT powinny być włączone tylko wtedy, gdy potrzebujesz obsługi skryptów i pracujesz w w pełni zaufanym środowisku.

msxsl:script, definicja elementu

Element msxsl:script jest rozszerzeniem firmy Microsoft do zalecenia XSLT 1.0 i ma następującą definicję:

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

Prefiks msxsl jest powiązany z identyfikatorem urn:schemas-microsoft-com:xslt URI przestrzeni nazw. Arkusz stylów musi zawierać deklarację xmlns:msxsl=urn:schemas-microsoft-com:xslt przestrzeni nazw.

Atrybut language jest opcjonalny. Jego wartością jest język kodu osadzonego bloku kodu. Język jest mapowany na odpowiedni kompilator CodeDOM przy użyciu CodeDomProvider.CreateProvider metody . Klasa XslCompiledTransform może obsługiwać dowolny język Microsoft .NET, zakładając, że odpowiedni dostawca jest zainstalowany na maszynie i jest zarejestrowany w sekcji system.codedom pliku machine.config. language Jeśli atrybut nie zostanie określony, język zostanie domyślnie określony w języku JScript. Nazwa języka nie uwzględnia wielkości liter, więc "JavaScript" i "javascript" są równoważne.

Atrybut implements-prefix jest obowiązkowy. Ten atrybut służy do deklarowania przestrzeni nazw i kojarzenia jej z blokiem skryptu. Wartość tego atrybutu jest prefiks, który reprezentuje obszar nazw. Ten prefiks można zdefiniować gdzieś w arkuszu stylów.

Uwaga

W przypadku korzystania z elementu zdecydowanie zalecamy umieszczenie skryptu msxsl:script niezależnie od języka w sekcji CDATA. Ponieważ skrypt może zawierać operatory, identyfikatory lub ograniczniki dla danego języka, jeśli nie jest on zawarty w sekcji CDATA, może być błędnie interpretowany jako kod XML. Poniższy kod XML przedstawia szablon sekcji CDATA, w której można umieścić kod.

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

Funkcje skryptu

Funkcje można zadeklarować w elemecie msxsl:script . Po zadeklarowaniu funkcji jest ona zawarta w bloku skryptu. Arkusze stylów mogą zawierać wiele bloków skryptów, z których każdy działa niezależnie od innych. Oznacza to, że jeśli wykonujesz wewnątrz bloku skryptu, nie można wywołać funkcji zdefiniowanej w innym bloku skryptu, chyba że zostanie zadeklarowana, że ma tę samą przestrzeń nazw i ten sam język skryptów. Ponieważ każdy blok skryptu może znajdować się we własnym języku, a blok jest analizowany zgodnie z regułami gramatycznymi tego analizatora języka, zalecamy użycie poprawnej składni używanego języka. Jeśli na przykład jesteś w bloku skryptów języka Microsoft C#, użyj składni komentarza języka C#.

Podane argumenty i zwracane wartości do funkcji mogą być dowolnego typu. Ponieważ typy XPath W3C są podzbiorem typów środowiska uruchomieniowego języka wspólnego (CLR), konwersja typów odbywa się na typach, które nie są uważane za typ XPath. W poniższej tabeli przedstawiono odpowiednie typy W3C i równoważny typ CLR.

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

Typy liczbowe CLR są konwertowane na Double. Typ DateTime jest konwertowany na String. IXPathNavigable typy są konwertowane na XPathNavigator. Klasa XPathNavigator[] jest konwertowana na XPathNodeIterator.

Wszystkie inne typy zgłaszają błąd.

Importowanie przestrzeni nazw i zestawów

Klasa XslCompiledTransform wstępnie określa zestaw zestawów i przestrzeni nazw, które są domyślnie obsługiwane przez msxsl:script element . Można jednak użyć klas i składowych należących do przestrzeni nazw, która nie znajduje się na wstępnie zdefiniowanej liście, importując zestaw i przestrzeń nazw w msxsl:script bloku.

Zestawy

Domyślnie odwołują się do następujących dwóch zestawów:

  • PLik System.dll

  • System.Xml.dll

  • Microsoft.VisualBasic.dll (gdy język skryptu to VB)

Dodatkowe zestawy można zaimportować przy użyciu msxsl:assembly elementu . Obejmuje to zestaw podczas kompilowania arkusza stylów. Element msxsl:assembly ma następującą definicję:

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

Atrybut name zawiera nazwę zestawu, a href atrybut zawiera ścieżkę do zestawu. Nazwa zestawu może być pełną nazwą, taką jak "System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" lub krótka nazwa, taka jak "System.Web".

Przestrzenie nazw

Następujące przestrzenie nazw są domyślnie uwzględniane:

  • System

  • System.Collection

  • System.Text

  • System.Text.RegularExpressions

  • System.Xml

  • System.Xml.Xsl

  • System.Xml.XPath

  • Microsoft.VisualBasic (gdy język skryptu to VB)

Możesz dodać obsługę dodatkowych przestrzeni nazw przy użyciu atrybutu namespace . Wartość atrybutu jest nazwą przestrzeni nazw.

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

Przykład

W poniższym przykładzie użyto osadzonego skryptu do obliczenia obwodu okręgu na podstawie jego promienia.

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>

Wynik

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

Zobacz też