XSLT 体系结构在 Visual Studio 2005 版本中进行了重新设计。 该 XslTransform 类已替换为该 XslCompiledTransform 类。
以下几个部分介绍XslCompiledTransform类与XslTransform类之间的一些主要差异。
性能
XslCompiledTransform 类包含许多性能改进。 新的 XSLT 处理器将 XSLT 样式表编译为通用中间格式,类似于公共语言运行时(CLR)对其他编程语言执行的作。 编译样式表后,可以缓存并重复使用该样式表。
该 XslCompiledTransform 类还包括其他优化,使其比 XslTransform 类快得多。
注释
虽然XslCompiledTransform类的整体性能优于XslTransform类,但当XslCompiledTransform类的Load方法首次调用转换时,其执行速度可能比XslTransform类的Load方法更慢。 这是因为必须在加载 XSLT 文件之前对其进行编译。 有关详细信息,请参阅以下博客文章: XslCompiledTransform 比 XslTransform 慢?
安全
默认情况下,该 XslCompiledTransform 类禁用对 XSLT document()
函数和嵌入式脚本的支持。 可以通过创建一个启用了功能的XsltSettings对象,并将其传递给Load方法来启用这些功能。 以下示例演示如何启用脚本和执行 XSLT 转换。
注释
脚本块仅在 .NET Framework 中受支持。 .NET Core 或 .NET 5 或更高版本 不支持 它们。
// Create the XsltSettings object with script enabled.
XsltSettings settings = new XsltSettings(false,true);
// Execute the transform.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("calc.xsl", settings, new XmlUrlResolver());
xslt.Transform("books.xml", "books.html");
' Create the XsltSettings object with script enabled.
Dim settings As New XsltSettings(False, True)
' Execute the transform.
Dim xslt As New XslCompiledTransform()
xslt.Load("calc.xsl", settings, New XmlUrlResolver())
xslt.Transform("books.xml", "books.html")
有关详细信息,请参阅 XSLT 安全注意事项。
新功能
临时文件
临时文件有时在 XSLT 处理期间生成。 如果样式表包含脚本块,或者使用设置为 true 的调试设置进行编译,可以在 %TEMP% 文件夹中创建临时文件。 在某些情况下,某些临时文件由于计时问题而未删除。 例如,如果文件由当前 AppDomain 或调试器使用,则 TempFileCollection 对象的终结器将无法删除它们。
该 TemporaryFiles 属性可用于其他清理,以确保从客户端中删除所有临时文件。
对 xsl:output 元素和 XmlWriter 的支持
将转换输出发送到XmlWriter对象时,类XslTransform将xsl:output
忽略设置。 该XslCompiledTransform类具有一个属性,该属性返回一个OutputSettingsXmlWriterSettings对象,该对象包含派生自xsl:output
样式表元素的输出信息。 该 XmlWriterSettings 对象用于创建 XmlWriter 具有可传递给 Transform 方法的正确设置的对象。 以下 C# 代码演示了此行为:
// Create the XslTransform object and load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(stylesheet);
// Load the file to transform.
XPathDocument doc = new XPathDocument(filename);
// Create the writer.
XmlWriter writer = XmlWriter.Create(Console.Out, xslt.OutputSettings);
// Transform the file and send the output to the console.
xslt.Transform(doc, writer);
writer.Close();
调试选项
该 XslCompiledTransform 类可以生成调试信息,使你能够使用 Microsoft Visual Studio Debugger 调试样式表。 有关详细信息,请参阅 XslCompiledTransform(Boolean)。
行为差异
转换为 XmlReader
该 XslTransform 类具有多个转换重载,这些重载将转换结果作为对象 XmlReader 返回。 这些重载可用于将转换结果加载到内存中表示形式(例如 XmlDocument 或 XPathDocument),而不会产生生成的 XML 树的序列化和反序列化开销。 以下 C# 代码演示如何将转换结果加载到对象 XmlDocument 中。
// Load the style sheet
XslTransform xslt = new XslTransform();
xslt.Load("MyStylesheet.xsl");
// Transform input document to XmlDocument for additional processing
XmlDocument doc = new XmlDocument();
doc.Load(xslt.Transform(input, (XsltArgumentList)null));
该 XslCompiledTransform 类不支持转换为 XmlReader 对象。 但是,你可以使用CreateNavigator方法直接从XmlWriter加载生成的 XML 树,以执行类似的操作。 以下 C# 代码展示了如何使用 XslCompiledTransform 完成相同的任务。
// Transform input document to XmlDocument for additional processing
XmlDocument doc = new XmlDocument();
using (XmlWriter writer = doc.CreateNavigator().AppendChild()) {
xslt.Transform(input, (XsltArgumentList)null, writer);
}
自由裁量行为
W3C XSL 转换 (XSLT) 1.0 版建议中涉及到实现提供者可以在哪些方面确定如何处理某种情况。 这些领域被视为自由裁量行为。 有几个方面,XslCompiledTransform 的行为与 XslTransform 类不同。 有关详细信息,请参阅 可恢复的 XSLT 错误。
扩展对象和脚本函数
XslCompiledTransform 引入了两个新的脚本函数使用限制:
只能从 XPath 表达式调用公共方法。
重载之间可以基于自变量数量进行区分。 如果多个重载具有相同数量的参数,则将引发异常。
在 XslCompiledTransform 中,脚本函数的绑定(方法名称查找)发生在编译时,当使用 XslCompiledTransform 加载由 XslTranform 使用的样式表时,这些样式表可能会引发异常。
XslCompiledTransform支持在msxsl:script
元素中同时包含msxsl:using
和msxsl:assembly
子元素。 和msxsl:using
msxsl:assembly
元素用于声明其他命名空间和程序集,以便在脚本块中使用。 有关详细信息,请参阅 使用 msxsl:script 的脚本块 。
XslCompiledTransform 禁止具有具有相同数量的参数的多个重载的扩展对象。
MSXML 函数
已将其他 MSXML 函数的支持添加到该 XslCompiledTransform 类。 以下列表描述了新功能或改进的功能:
msxsl:node-set:XslTransform 需要 node-set 函数 的参数是结果树片段。 该 XslCompiledTransform 类没有此要求。
msxsl:version:此函数受 XslCompiledTransform支持。
XPath 扩展函数:ms:string-compare 函数、ms:utc 函数、ms:namespace-uri 函数、ms:local-name 函数、ms:number 函数、ms:format-date 函数和ms:format-time 函数现已受支持。
架构相关的 XPath 扩展函数:这些函数未被 XslCompiledTransform 原生支持。 但是,它们可以作为扩展函数实现。