XslCompiledTransform 類別支援使用 msxsl:script 項目的內嵌指令碼。 載入樣式表時,程式碼文件物件模型 (CodeDOM) 會將任何已定義的函式編譯成 Microsoft Intermediate Language (MSIL),並在執行階段期間執行。 從內嵌指令碼區塊產生的組件不同於為樣式表產生的組件。
啟用 XSLT 指令碼
內嵌指令碼支援是 XslCompiledTransform 類別上的選擇性 XSLT 設定。 預設會停用指令碼支援。 若要啟用指令碼支援,請建立 XsltSettings 物件 (將 EnableScript 屬性設為 true),並將該物件傳遞至 Load 方法。
注意事項 |
|---|
僅當需要指令碼支援且在完全受信任的環境中運作時,才應啟用 XSLT 指令碼。如需詳細資訊,請參閱 System.Xml 安全性考量。 |
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 型別是 Common Language Runtime (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>
注意事項