XslTransform 类支持使用 script 元素的嵌入脚本撰写。加载样式表时,任何已定义的函数都会通过包装在类定义中来编译为 Microsoft 中间语言 (MSIL),因此不会有任何性能损失。
<msxsl:script> 元素定义如下:
<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>
其中 msxsl 是绑定到命名空间 urn:schemas-microsoft-com:xslt 的前缀。
language 属性不是强制的,但如果指定,则它的值必须是下列语言之一:C#、VB、JScript、JavaScript、VisualBasic 或 CSharp。如果未指定,则默认语言为 JScript。language-name 不区分大小写,因此“JavaScript”和“javascript”是等效的。
implements-prefix 属性是强制的。此属性用于声明命名空间并将其与脚本块关联。此属性的值是表示命名空间的前缀。此命名空间可以在样式表中的某一位置定义。
因为 msxsl:script 元素属于命名空间 urn:schemas-microsoft-com:xslt,因此样式表必须包含命名空间声明 xmlns:msxsl=urn:schemas-microsoft-com:xslt。
如果脚本的调用方没有
如果调用方有 UnmanagedCode 权限,则脚本将编译,但允许的操作取决于加载时提供的证据。
如果您在使用采用 XmlReader 或 XPathNavigator 作为参数的 Load 方法之一加载样式表,则需要使用采用
若要从您的程序集中得到证据,请使用 this.GetType().Assembly.Evidence。若要从 URI 得到证据,请使用 Evidence e = XmlSecureResolver.CreateEvidenceForUrl(stylesheetURI)。
如果使用采用 XmlResolver 作为参数但没有 Evidence 的 Load 方法,则程序集的安全区域默认为“完全信任”。有关更多信息,请参见
函数可以在 msxsl:script 元素内声明。下表显示了默认情况下支持的命名空间。可以在列出的命名空间的外部使用类。然而,这些类必须是完全限定的。
| 默认命名空间 | 说明 |
|---|---|
| System | 系统类。 |
| System.Collection | 集合类。 |
| System.Text | 文本类。 |
| System.Text.RegularExpressions | 正则表达式类。 |
| System.Xml | 核心 XML 类。 |
| System.Xml.Xsl | XSLT 类。 |
| System.Xml.XPath | XPath 类。 |
| Microsoft.VisualBasic | 用于 Visual Basic 脚本的类。 |
声明函数时,该函数包含在脚本块中。样式表可以包含多个脚本块,它们的运行彼此独立。也就是说,如果在脚本块的内部执行,则无法调用在其他脚本块中定义的函数,除非该脚本块声明为具有同一命名空间和同一脚本语言。由于每个脚本块都可以使用自己的语言,因此脚本块的分析将遵照该语言分析器的语法规则进行。使用的语法对于所用的语言而言必须是正确的。例如,如果使用的是 C# 脚本块,则在该块中使用 XML 注释节点 <!-- an XML comment --> 是错误的。
所提供的参数以及由脚本函数定义的返回值必须是 W3C XPath 或 XSLT 类型之一。下表显示了相应的 W3C 类型、等效的 .NET 类(类型),以及 W3C 类型是 XPath 类型还是 XSLT 类型。
| 类型 | 等效的 .NET 类(类型) | XPath 类型或 XSLT 类型 |
|---|---|---|
| String | System.String | XPath |
| Boolean | System.Boolean | XPath |
| Number | System.Double | XPath |
| 结果树片段 | System.Xml.XPath.XPathNavigator | XSLT |
| 节点集 | System.Xml.XPath.XPathNodeIterator | XPath |
如果脚本函数使用下列数值类型之一:Int16、UInt16、Int32、UInt32、Int64、UInt64、Single 或 Decimal,这些类型将被强制指定为 Double,而 Double 映射为 W3C XPath 类型数字。所有其他类型都通过调用 ToString 方法强制转换为字符串。
如果脚本函数使用上述类型以外的类型,或者如果函数在样式表加载到 XslTransform 对象中时不进行编译,则会引发异常。
当使用 msxsl:script 元素时,强烈建议无论使用何种语言,都应将脚本放置在 CDATA 节内。例如,下面的 XML 显示放置代码的 CDATA 节的模板。
<msxsl:script implements-prefix='yourprefix' language='CSharp'>
<![CDATA[
... your code here ...
]]>
</msxsl:script>
强烈建议将所有脚本内容都放置在 CDATA 节内,因为给定语言的运算符、标识符或分隔符有可能被错误地解释为 XML。下面的示例显示如何在脚本中使用逻辑 AND 运算符。(这是根据XML的特性决定的解决方案,因为特殊字符的存在所以必须放在CDATA区域内)
<msxsl:script implements-prefix='yourprefix' language='CSharp>
public string book(string abc, string xyz)
{ if ((abc== abc)&&(abc== xyz)) return bar+xyz;
else return null;
}
</msxsl:script>
由于“&”符没有转义,因此这将引发异常。将文档作为 XML 加载,并且不对 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() {
//Create the XslTransform and load the stylesheet.
XslTransform xslt = new XslTransform();
xslt.Load(stylesheet);
//Load the XML data file.
XPathDocument doc = new XPathDocument(filename);
//Create an XmlTextWriter to output to the console.
XmlTextWriter writer = new XmlTextWriter(Console.Out);
writer.Formatting = Formatting.Indented;
//Transform the file.
xslt.Transform(doc, null, writer, null);
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>
浙公网安备 33010602011771号