match 関数を使って要素を選択する際に正規表現を使用したいと考えています。これを行うために外部ライブラリ (saxon など) を使用したくありません。
6 に答える
この議論の答えは誤解を招くものだと思います。.NET 3.5 はほとんどの XSL/T 2.0 関数をサポートしていないと思います (もしあったとしても)。
例:
2.0 関数を呼び出すと、.NET 3.5 で次のエラー メッセージが表示されます。
「current-dateTime()」は不明な XSLT 関数です。
上記の答えは間違っていると思います。MicrosoftがXSLT2.0をサポートしているという証拠は見つかりません。XSLT!=XPath。
XSLT 2.0 には組み込みライブラリでサポートされていないものがいくつかあります (これについて mono メーリング リストで議論がありましたが、もう情報を見つけることができません)。しかし、ほとんどの人は、サポートされていないコーナー ケースに遭遇することはありません。
もう 1 つのオプションは、オープン ソースhttp://saxon.sourceforge.net/をチェックすることです。これは 2.0 を強力にサポートしています。
編集(AB):上記の受け入れられた回答は混乱を招く可能性があります。.NET の XPath 2.0 または XSLT 2.0 関数のサポートはまったくなく、その方向の計画もありません。
XSLT 2.0、XPath 2.0、および XQuery 1.0 の .NET サポートについて議論する場合、言語自体とデータ モデル (XDM) を区別することが重要です。.NET 3.5 Framework はデータ モデルをサポートしていますが、言語はサポートしていません。Microsoft の Pawel Kadluczka から電子メールで最近説明されたとおりです。
「XQuery 1.0 および XPath 2.0 データ モデルのインスタンス」という文は紛らわしいかもしれませんが、W3C XQuery 1.0 および XPath 2.0 データ モデル (XDM) 仕様 ( http://www.w3.org/TR/xpath- datamodel ) を読みます:
[定義: データ モデルのすべてのインスタンスはシーケンスです。].
[定義: シーケンスは、0 個以上の項目の順序付けられたコレクションです。] シーケンスは、シーケンスのメンバーになることはできません。単独で表示される単一のアイテムは、1 つのアイテムを含むシーケンスとしてモデル化されます。シーケンスは、2.5 シーケンスで定義されています。
[定義: 項目はノードまたは原子値のいずれかです],
XPath API の場合、XPathNodeIterator はシーケンスであり、XPathItem (XPathNavigator) は項目を表します。
今後の参考のために、.net での xpath/xquery の拡張に関するすばらしいページを次に示します。
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=64
これが続くとは思えないので、ここにコピーします。
XSLT は XML の変換言語です。これにより、サーバー システムはソース XML ツリーをクライアントにより適した形式に変換できます。XSLT はノード パターンを使用してテンプレートと照合し、その変換を実行します。複雑な変換を比較的単純にしますが、いくつかのカスタム クラスを使用しなければならない場合があります。
XSLT を拡張する必要がある状況には、次のようなものがあります。
1) カスタム ビジネス ロジックを呼び出す
2) アクセス許可に応じてさまざまなアクションを実行する
3) 日付、文字列などの複雑な書式設定を実行する
4) または、Web サービスを呼び出すこともできます!!
XSLT を拡張する手順
1) XSLT 内から使用するカスタム オブジェクトを作成する (C# の場合)
CustomDate custDate = new CustomDate() ;
2) XSLTs 名前空間宣言 (XSLT ファイル内) 内でカスタム クラスのカスタム名前空間宣言を提供します。
<xsl:transform
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myCustDate="urn:custDate">
3) 最後のステップ (C#) と同じ名前空間を使用して、カスタム オブジェクトのインスタンスを XSLT に渡します。
xslArgs.AddExtensionObject("urn:custDate", custDate) ;
4) XSLT 内 (XSLT ファイル内) からオブジェクトを使用する
<xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/>
サンプルコード
この例では、日付を操作する必要がある XSLT シートがあると仮定します。従業員が会社に在籍した日数を示す必要があります。XSLT にはネイティブの日付操作関数がないため、タスクに拡張オブジェクトを使用しましょう。
using System ;
using System.IO ;
using System.Xml ;
using System.Xml.Xsl ;
using System.Xml.XPath ;
public class XsltExtension{
public static void Main(string[] args){
if (args.Length == 2){
Transform(args[0], args[1]) ;
}else{
PrintUsage() ;
}
}
public static void Transform(string sXmlPath, string sXslPath){
try{
//load the Xml doc
XPathDocument myXPathDoc = new XPathDocument(sXmlPath) ;
XslTransform myXslTrans = new XslTransform() ;
//load the Xsl
myXslTrans.Load(sXslPath) ;
XsltArgumentList xslArgs = new XsltArgumentList() ;
//create custom object
CustomDate custDate = new CustomDate() ;
//pass an instance of the custom object
xslArgs.AddExtensionObject("urn:custDate", custDate) ;
//create the output stream
XmlTextWriter myWriter = new XmlTextWriter("extendXSLT.html", null) ;
//pass the args,do the actual transform of Xml
myXslTrans.Transform(myXPathDoc,xslArgs, myWriter) ;
myWriter.Close() ;
}catch(Exception e){
Console.WriteLine("Exception: {0}", e.ToString());
}
}
public static void PrintUsage(){
Console.WriteLine("Usage: XsltExtension.exe <xml path> >xsl path<") ;
}
}
//our custom class
public class CustomDate{
//function that gets called from XSLT
public string GetDateDiff(string xslDate){
DateTime dtDOB = DateTime.Parse(xslDate) ;
DateTime dtNow = DateTime.Today ;
TimeSpan tsAge = dtNow.Subtract(dtDOB) ;
return tsAge.Days.ToString() ;
}
}
このコードをコンパイルし、提供された members.xml と memberdisplay.xsl を使用して、このコンソール アプリケーションを実行します。同じフォルダー内にextendXSLT.htmlファイルが表示されます。このファイルを開くと、クラス CustomDate が呼び出され、従業員の在職日数が計算されていることに注意してください。
概要 :
XSLT は XML の強力な変換言語ですが、.NET と C# で拡張オブジェクトを使用すると、XSLT だけでは不可能または困難なことを簡単に達成できるようになります。
メンバー.xml:
<root>
<member>
<name>Employee1</name>
<joiningdate>01/01/1970</joiningdate>
<role>CTO</role>
</member>
<member>
<name>Employee2</name>
<joiningdate>24/07/1978</joiningdate>
<role>Web Developer</role>
</member>
<member>
<name>Employee3</name>
<joiningdate>15/12/1980</joiningdate>
<role>Tester</role>
</member>
</root>
メンバー表示.xsl:
<xsl:transform
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myCustDate="urn:custDate">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="/">
<html>
<head>
<style>
TABLE.tblMaster
{
border-style: solid;
border-width: 1px 1px 1px 1px;
border-style: solid;
border-color: #99CCCC;
padding: 4px 6px;
text-align: left;
font-family:Tahoma,Arial;
font-size:9pt;
}
TD.tdHeader
{
FONT-WEIGHT: bolder;
FONT-FAMILY: Arial;
BACKGROUND-COLOR: lightgrey;
TEXT-ALIGN: center
}
</style>
</head>
<body>
<table width="50%" class="tblMaster">
<tr >
<td class="tdHeader">Employee</td>
<td class="tdHeader">Join date</td>
<td class="tdHeader">Days in company</td>
<td class="tdHeader">Role</td>
</tr>
<xsl:for-each select="/root/member">
<tr >
<td> <xsl:value-of select="./name"/> </td>
<td> <xsl:value-of select="./joiningdate"/> </td>
<td> <xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/> </td>
<td> <xsl:value-of select="./role"/> </td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:transform>
はい、3.5XPathNavigatorはXSLT2.0をサポートしています。
http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx
「System.Xml.XPath名前空間のXPathNavigatorクラスは、XML情報アイテムをXQuery1.0およびXPath2.0データモデルのインスタンスとしてナビゲートおよび編集するためのカーソルモデルを定義する抽象クラスです。」