備註
只有 .NET Framework 才支援腳本區塊。 .NET Core 或 .NET 5 或更新版本 不支持 它們。
類別 XslCompiledTransform 支援透過 msxsl:script 元素內嵌腳本。 當樣式表載入時,任何定義的函式會由程式碼文件物件模型(Code Document Object Model,CodeDOM)編譯成通用中間語言(CIL),並在執行時執行。 從內嵌腳本區塊產生的元件與為樣式表單產生的元件不同。
啟用 XSLT 指令碼
在XslCompiledTransform類別上的內嵌腳本支援是可選的XSLT設定。 預設會停用腳本支援。 若要啟用文本支援,請建立 XsltSettings 屬性設定為 EnableScript 的物件true,並將 對象傳遞至 Load 方法。
警告
從 .NET 10 開始,屬性 EnableScript 會標示為過時,並產生警告SYSLIB0062。 由於 .NET Core 或 .NET 5+ 不支援腳本區塊,這個屬性沒有影響,設定為 true 執行時會拋出 a PlatformNotSupportedException 。
備註
只有在需要腳本支援且在完全信任的環境中工作時,才應該啟用 XSLT 腳本。
msxsl:指令碼元素定義
元素 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 類型是 Common Language Runtime (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>