Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Замечание
Блоки скриптов поддерживаются только в .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>