Блоки скриптов с использованием msxsl:script
Класс XslCompiledTransform поддерживает внедренные скрипты с помощью элемента msxsl:script. После загрузки таблицы стилей все определенные функции компилируются в MSIL с помощью модели CodeDOM и выполняются во время выполнения. Сборка, создаваемая из блока внедренного скрипта, располагается отдельно от сборки, создаваемой для таблицы стилей.
Включение скрипта XSLT
Поддержка внедренных скриптов является необязательным параметром XSLT в классе XslCompiledTransform. По умолчанию поддержка скриптов отключена. Чтобы включить поддержку скриптов, создайте объект XsltSettings со значением свойства EnableScript, равным true, и передайте его методу Load.
Примечание |
---|
Скрипты XSLT следует включать только при необходимости в поддержке скриптов и при работе в полностью доверенной среде.Дополнительные сведения см. в разделе Рекомендации по безопасности System.Xml. |
Определение элемента msxsl:script
Элемент msxsl:script введен корпорацией Майкрософт в качестве расширения рекомендации XSLT 1.0 и имеет следующее определение:
<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>
Префикс msxsl привязан к URI-коду пространства имен urn:schemas-microsoft-com:xslt. Таблица стилей должна содержать декларацию пространства имен 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#.
Передаваемые аргументы и возвращаемые значения функции могут иметь любой тип. Поскольку типы W3C XPath являются подмножеством типов среды CLR, для типов, которые не относятся к XPath, выполняется преобразование типов. В следующей таблице показано соответствие типов W3C и типов среды CLR.
Тип W3C |
Тип CLR |
---|---|
String |
|
Boolean |
|
Number |
|
Result Tree Fragment |
|
Node Set |
Числовые типы среды 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=b77a5c561934e089», или кратким, таким как «System.Web».
Пространства имен
По умолчанию включаются следующие пространства имен:
System;
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>
Пример
В следующем примере используется внедренный скрипт для вычисления длины окружности по заданному радиусу.
Imports System
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
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();
}
}
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>
См. также
Основные понятия
Рекомендации по безопасности XSLT