注释
脚本块仅在 .NET Framework 中受支持。 .NET Core 或 .NET 5 或更高版本 不支持 它们。
XslCompiledTransform 类支持使用 msxsl:script
元素来嵌入脚本。 加载样式表时,代码文档对象模型(CodeDOM)会将任何定义的函数编译为公共中间语言(CIL),并在运行时执行。 从嵌入脚本块生成的程序集与为样式表生成的程序集分开。
启用 XSLT 脚本
对嵌入式脚本的支持是 XslCompiledTransform 类的一个可选 XSLT 设置。 默认情况下禁用脚本支持。 若要启用脚本支持,请创建一个XsltSettings对象,并将EnableScript属性设置为true
,然后将该对象传递给Load方法。
注释
仅当需要脚本支持并且正在使用完全受信任的环境中时,才应启用 XSLT 脚本。
msxsl:script 元素定义
该 msxsl:script
元素是 XSLT 1.0 建议的Microsoft扩展,具有以下定义:
<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
属性是可选项。 其值是嵌入代码块的代码语言。 此语言通过 CodeDomProvider.CreateProvider 方法映射到相应的 CodeDOM 编译器。 该 XslCompiledTransform 类可以支持任何Microsoft .NET 语言,假设相应的提供程序安装在计算机上,并在 machine.config 文件的 system.codedom 节中注册。
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 |
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=b77a5c561934e089”或短名称,如“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>