スタイル シート パラメータと拡張オブジェクト用の XsltArgumentList

更新 : November 2007

XsltArgumentList クラスには、XSLT (Extensible Stylesheet Language for Transformations) パラメータと XSLT 拡張オブジェクトが含まれています。これらのパラメータと拡張オブジェクトは、Transform メソッドに渡すことで、スタイル シートから呼び出せるようになります。

ts9by56w.alert_note(ja-jp,VS.90).gifメモ :

.NET Framework version 2.0 では、XslTransform クラスと XsltArgumentList クラスが廃止されています。XslCompiledTransform クラスを使用して XSLT 変換を実行できます。詳細については、「XslCompiledTransform クラスの使用」および「XslTransform クラスからの移行」を参照してください。

XsltArgumentList クラスには、XSLT パラメータと XSLT 拡張オブジェクトが含まれています。これらのパラメータと拡張オブジェクトは、Transform メソッドに渡すことで、スタイル シートから呼び出せるようになります。

埋め込みスクリプトを使用するのではなく、オブジェクトを渡す利点を次に示します。

  • クラスをより効果的にカプセル化および再利用できます。

  • スタイル シートを小さくすることができ、管理が簡単になります。

  • サポートされている System 名前空間のセット内で定義されているもの以外の名前空間に属しているクラスのメソッドを呼び出すことができます。

  • XPathNodeIterator を使用して結果ツリー フラグメントをスタイル シートに渡す操作がサポートされます。

XSLT スタイル シートのパラメータ

XSLT パラメータを XsltArgumentList に追加するには、AddParam メソッドを使用します。パラメータが追加された時点で、修飾名と名前空間 URI (Uniform Resource Identifier) がそのパラメータ オブジェクトに関連付けられます。

パラメータ オブジェクトは、W3C (World Wide Web Consortium) 型に対応している必要があります。対応する W3C 型、それと同等の .NET Framework のクラス (型)、および W3C 型が XPath (XML Path Language) 型または XSLT 型のどちらかを次の表に示します。

W3C 型

対応する .NET Framework クラス (型)

XPath 型または XSLT 型

String

System.String

XPath

Boolean

System.Boolean

XPath

Number

System.Double

XPath

Result Tree Fragment

System.Xml.XPath.XPathNavigator

XSLT

Node Set

System.Xml.XPath.XPathNodeIterator

XPath

パラメータ オブジェクトが上に示したクラスでない場合は、クラスの種類に応じて、Double または String に強制的に変換されます。Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Decimal の各型は、強制的に Double に変換されます。その他すべての型は、ToString メソッドを使用して強制的に文字列に変換されます。

XSLT パラメータを使用するために必要な処理

  1. XsltArgumentList を作成し、AddParam を使用してオブジェクトを追加します。

  2. スタイル シートからパラメータを呼び出します。

  3. XsltArgumentListTransform メソッドに渡します。

算出された割引日を保持するパラメータを AddParam メソッドを使用して作成する例を次に示します。割引日は、発注日から 20 日後として算出されます。

Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports System.Xml.Xsl

Public class Sample

   Private Const filename As String = "order.xml"
   Private Const stylesheet As String = "discount.xsl"

   Public Shared Sub Main()

    'Create the XslTransform and load the style sheet.
    Dim xslt As XslTransform = New XslTransform
    xslt.Load(stylesheet)

    'Load the XML data file.
    Dim doc As XPathDocument = New XPathDocument(filename)

    'Create an XsltArgumentList.
    Dim xslArg As XsltArgumentList = New XsltArgumentList
         
    'Calculate the discount date.
    Dim today As DateTime = DateTime.Now
    Dim d As DateTime = today.AddDays(20)
    xslArg.AddParam("discount", "", d.ToString())

    'Create an XmlTextWriter to handle the output.
    Dim writer As XmlTextWriter = New XmlTextWriter("orderout.xml", Nothing)

    'Transform the file.
    xslt.Transform(doc, xslArg, writer, Nothing)

    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 = "order.xml";
   private const String stylesheet = "discount.xsl";

   public static void Main() {

    //Create the XslTransform and load the style sheet.
    XslTransform xslt = new XslTransform();
    xslt.Load(stylesheet);

    //Load the XML data file.
    XPathDocument doc = new XPathDocument(filename);

    //Create an XsltArgumentList.
    XsltArgumentList xslArg = new XsltArgumentList();
         
    //Calculate the discount date.
    DateTime today = DateTime.Now;
    DateTime d = today.AddDays(20);
    xslArg.AddParam("discount", "", d.ToString());

    //Create an XmlTextWriter to handle the output.
    XmlTextWriter writer = new XmlTextWriter("orderout.xml", null);

    //Transform the file.
    xslt.Transform(doc, xslArg, writer, null);
    writer.Close();
  }
}

入力

order.xml

<!--Represents a customer order-->
<order>
  <book ISBN='10-861003-324'>
    <title>The Handmaid's Tale</title>
    <price>19.95</price>
  </book>
  <cd ISBN='2-3631-4'>
    <title>Americana</title>
    <price>16.95</price>
  </cd>
</order>

discount.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="discount"/>
  <xsl:template match="/">
    <order>
      <xsl:variable name="sub-total" select="sum(//price)"/>
      <total><xsl:value-of select="$sub-total"/></total>
      15% discount if paid by: <xsl:value-of select="$discount"/>
    </order>
  </xsl:template>
</xsl:stylesheet>

出力

<order>
   <total>36.9</total> 
   15% discount if paid by: 5/6/2001 5:01:15 PM 
</order>

XSLT 拡張オブジェクト

XSLT 拡張オブジェクトを XsltArgumentList に追加するには、AddExtensionObject メソッドを使用します。その時点で、修飾名と名前空間 URI がその拡張オブジェクトに関連付けられます。

オブジェクトを追加する場合、AddExtensionObject の呼び出し元は、セキュリティ ポリシーで完全に信頼されている必要があります。呼び出し元の信頼性が低いと、処理は失敗します。

オブジェクトは正常に追加されますが、正常に実行されるかどうかは保証されません。Transform メソッドを呼び出すと、Load の実行時に指定された証拠に基づいてアクセス許可が計算され、そのアクセス許可セットが変換処理全体に割り当てられます。拡張オブジェクトが、アクセス許可セットにないアクセス許可を必要とする処理を実行しようとすると、例外がスローされます。

拡張オブジェクトが返すデータ型は、4 つの基本 XPath 型である数値、文字列、ブール、ノード セットのうちのいずれかになります。

XSLT 拡張オブジェクトを使用するために必要な処理

  1. XsltArgumentList を作成し、AddExtensionObject を使用して拡張オブジェクトを追加します。

  2. スタイル シートから拡張オブジェクトを呼び出します。

  3. XsltArgumentListTransform メソッドに渡します。

半径が指定された円の円周を算出する例を次に示します。

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 = "circle.xsl"

   Public Shared Sub Main()
        Dim test As Sample = New Sample
   End Sub
    
  Public Sub New()
    'Create the XslTransform and load the style sheet.
    Dim xslt As XslTransform = New XslTransform
    xslt.Load(stylesheet)

    'Load the XML data file.
    Dim doc As XPathDocument = New XPathDocument(filename)

    'Create an XsltArgumentList.
    Dim xslArg As XsltArgumentList = New XsltArgumentList
         
    'Add an object to calculate the circumference of the circle.
    Dim obj As Calculate = New Calculate
    xslArg.AddExtensionObject("urn:myObj", obj)

    'Create an XmlTextWriter to output to the console.
    Dim writer As XmlTextWriter = New XmlTextWriter(Console.Out)

    'Transform the file.
    xslt.Transform(doc, xslArg, writer, Nothing)
    writer.Close()

  End Sub

  'Calculates the circumference of a circle given the radius.
  Public Class Calculate

    Private circ As double = 0
      
    Public Function Circumference(radius As Double) As Double
       circ = Math.PI*2*radius
       Return circ
    End Function
  End Class
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 = "circle.xsl";

   public static void Main() {

        Sample test = new Sample();
    }
    
  public Sample() {

    //Create the XslTransform and load the style sheet.
    XslTransform xslt = new XslTransform();
    xslt.Load(stylesheet);

    //Load the XML data file.
    XPathDocument doc = new XPathDocument(filename);

    //Create an XsltArgumentList.
    XsltArgumentList xslArg = new XsltArgumentList();
         
    //Add an object to calculate the circumference of the circle.
    Calculate obj = new Calculate();
    xslArg.AddExtensionObject("urn:myObj", obj);

    //Create an XmlTextWriter to output to the console.
    XmlTextWriter writer = new XmlTextWriter(Console.Out);

    //Transform the file.
    xslt.Transform(doc, xslArg, writer, null);
    writer.Close();

  }

  //Calculates the circumference of a circle given the radius.
  public class Calculate{

    private double circ = 0;
      
    public double Circumference(double radius){
       circ = Math.PI*2*radius;
       return circ;
    }
  }
}

入力

number.xml

<?xml version='1.0'?>
<data>
  <circle>
    <radius>12</radius>
  </circle>
  <circle>
    <radius>37.5</radius>
  </circle>
</data>  

circle.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:myObj="urn:myObj">

  <xsl:template match="data">
  <circles>
  <xsl:for-each select="circle">
    <circle>
    <xsl:copy-of select="node()"/>
       <circumference>
          <xsl:value-of select="myObj:Circumference(radius)"/>        
       </circumference>
    </circle>
  </xsl:for-each>
  </circles>
  </xsl:template>
</xsl:stylesheet>

出力

<circles xmlns:myObj="urn:myObj">

<circle>

<radius>12</radius>

<circumference>75.398223686155</circumference>

</circle>

<circle>

<radius>37.5</radius>

<circumference>235.61944901923448</circumference>

</circle>

</circles>

参照

概念

XslTransform クラスによる XSLT プロセッサの実装