次の方法で共有


msxsl:script を使用したスクリプト ブロック

スクリプト ブロックは、.NET Framework でのみサポートされています。 .NET Core または .NET 5 以降ではサポート されていません

XslCompiledTransform クラスは、msxsl:script要素を使用した埋め込みスクリプトをサポートします。 スタイル シートが読み込まれると、定義済みの関数はコード ドキュメント オブジェクト モデル (CodeDOM) によって共通中間言語 (CIL) にコンパイルされ、実行時に実行されます。 埋め込みスクリプト ブロックから生成されたアセンブリは、スタイル シート用に生成されたアセンブリとは別です。

XSLT スクリプトを有効にする

埋め込みスクリプトのサポートは、 XslCompiledTransform クラスのオプションの XSLT 設定です。 スクリプトのサポートは、既定では無効になっています。 スクリプトのサポートを有効にするには、EnableScript プロパティを true に設定してXsltSettings オブジェクトを作成し、そのオブジェクトを 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 クラスは、適切なプロバイダーがコンピューターにインストールされ、machine.config ファイルの system.codedom セクションに登録されていることを前提として、任意の Microsoft .NET 言語をサポートできます。 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 ブロックにインポートします。

アセンブリ

既定では、次の 2 つのアセンブリが参照されます。

  • 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>

こちらも参照ください