Поделиться через


Блоки скриптов с помощью msxsl:script

Замечание

Блоки скриптов поддерживаются только в .NET Framework. Они не поддерживаются в .NET Core или .NET 5 или более поздней версии.

Класс XslCompiledTransform поддерживает внедренные скрипты с помощью msxsl:script элемента. При загрузке таблицы стилей все определенные функции компилируются на общий промежуточный язык (CIL) моделью объектного документа кода (CodeDOM) и выполняются во время выполнения. Сборка, созданная из внедренного блока скриптов, отделена от сборки, созданной для таблицы стилей.

Включение сценария XSLT

Поддержка внедренных скриптов является необязательным параметром XSLT в XslCompiledTransform классе. Поддержка скриптов отключена по умолчанию. Чтобы включить поддержку скриптов, создайте объект XsltSettings с заданным свойством EnableScript равным true, и передайте этот объект в метод Load.

Предупреждение

Начиная с .NET 10 EnableScript свойство помечается как устаревшее и создает предупреждение SYSLIB0062. Так как блоки скриптов не поддерживаются в .NET Core или .NET 5+, это свойство не оказывает влияния, и его установка приводит к возникновению PlatformNotSupportedException в среде выполнения.

Замечание

Скрипты XSLT должны быть включены только в том случае, если требуется поддержка скриптов, и вы работаете в полностью доверенной среде.

Определение элемента msxsl:script

Элемент msxsl:script является расширением Майкрософт для рекомендации XSLT 1.0 и имеет следующее определение:

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

Префикс msxsl привязан к urn:schemas-microsoft-com:xslt URI пространства имен. Таблица стилей xmlns:msxsl=urn:schemas-microsoft-com:xslt должна содержать объявление пространства имен.

Атрибут language необязателен. Его значением является язык кода внедренного блока кода. Язык сопоставляется с соответствующим компилятором CodeDOM с помощью CodeDomProvider.CreateProvider метода. Класс XslCompiledTransform может поддерживать любой язык Microsoft .NET, если соответствующий поставщик установлен на компьютере и зарегистрирован в разделе system.codedom файла machine.config. language Если атрибут не указан, язык по умолчанию использует JScript. Имя языка не учитывает регистр, поэтому "JavaScript" и "javascript" эквивалентны.

Атрибут implements-prefix является обязательным. Этот атрибут используется для объявления пространства имен и связывания его с блоком скрипта. Значением этого атрибута является префикс, представляющий пространство имен. Этот префикс можно определить где-то в таблице стилей.

Замечание

При использовании msxsl:script элемента настоятельно рекомендуется поместить скрипт независимо от языка в раздел CDATA. Поскольку скрипт может содержать операторы, идентификаторы или разделители для данного языка, если он не содержится в разделе CDATA, он может быть неправильно интерпретирован как XML. В следующем XML-файле показан шаблон раздела CDATA, где можно разместить код.

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

Функции скрипта

Функции можно объявить в элементе msxsl:script . Когда функция объявлена, она содержится в блоке скрипта. Таблицы стилей могут содержать несколько блоков скриптов, каждый из которых работает независимо от другого. Это означает, что если вы выполняете внутри блока скриптов, нельзя вызывать функцию, определенную в другом блоке скриптов, если она не объявлена для того же пространства имен и того же языка сценариев. Поскольку каждый блок скрипта может быть на своем собственном языке, и анализ блока происходит согласно правилам грамматики анализатора этого языка, мы рекомендуем использовать правильный синтаксис для используемого языка. Например, если вы находитесь в блоке скриптов Microsoft C#, используйте синтаксис комментариев C#.

Указанные аргументы и возвращаемые значения функции могут иметь любой тип. Так как типы XPath W3C являются подмножеством типов среды CLR, преобразование типов происходит на типах, которые не считаются типом XPath. В следующей таблице показаны соответствующие типы W3C и эквивалентный тип CLR.

Тип W3C Тип среды CLR
String String
Boolean Boolean
Number Double
Result Tree Fragment XPathNavigator
Node Set XPathNodeIterator

Числовые типы CLR преобразуются в Double. Тип DateTime преобразуется в String. IXPathNavigable типы преобразуются в XPathNavigator. XPathNavigator[] преобразуется в XPathNodeIterator.

Все остальные типы вызывают ошибку.

Импорт пространств имен и сборок

Класс XslCompiledTransform предопределяет набор сборок и пространств имен, поддерживаемых по умолчанию элементом msxsl:script . Однако можно использовать классы и члены, которые принадлежат пространству имен, не включенному в предопределенный список, импортируя сборку и пространство имен в блоке msxsl:script.

Сборки

По умолчанию указываются следующие две сборки:

  • System.dll
  • System.Xml.dll
  • Microsoft.VisualBasic.dll (если язык скрипта — VB)

Дополнительные сборки можно импортировать с помощью msxsl:assembly элемента. Это включает процесс сборки при компиляции таблицы стилей. Элемент msxsl:assembly имеет следующее определение:

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

Атрибут name содержит имя сборки, а href атрибут содержит путь к сборке. Имя сборки может быть полным именем, например System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c5c561934e089 или коротким именем, например System.Web.

Пространства имен

По умолчанию включены следующие пространства имен:

  • Система
  • System.Collection
  • System.Text
  • System.Text.RegularExpressions
  • System.Xml
  • System.Xml.Xsl
  • System.Xml.XPath
  • Microsoft.VisualBasic (если язык скрипта — VB)

Вы можете добавить поддержку дополнительных пространств имен с помощью атрибута namespace . Значение атрибута — это имя пространства имен.

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

Пример

В следующем примере используется внедренный скрипт для вычисления окружности круга, заданного его радиусом.

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>

Выходные данные

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

См. также