我希望使用正则表达式在匹配函数中选择元素,但不想使用外部库(如saxon)来完成此操作。
我认为这个讨论中的答案是误导性的。我认为.NET 3.5不支持大多数XSL/T 2.0函数(如果有的话)。
一个例子:
在.NET 3.5下调用2.0函数会给出以下错误信息:
'current-dateTime()'是未知的XSLT函数。
为了以后参考,这里有一个有关在.net中扩展xpath/xquery的不错页面:
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=64
我不相信这个会长存,所以我把它复制到这里:
XSLT是一种用于XML变换的语言。它允许服务器系统将源XML树转换为更适合客户端的形式。XSLT使用节点模式来匹配模板以执行其转换。虽然它使得复杂的转换相对简单,但在某些情况下我们可能需要使用一些自定义类。
我们需要扩展XSLT的一些情况包括:
1) 调用自定义业务逻辑
2) 根据权限执行不同的操作
3) 对日期、字符串等进行复杂的格式化
4) 甚至调用webservice!!
扩展XSLT的步骤:
1) 创建要在XSLT内使用的自定义对象(C#中)
CustomDate custDate = new CustomDate() ;
2) 在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文件中使用对象
<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() ;
}
}
<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>
Memberdisplay.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.5 XPathNavigator 支持 XSLT 2.0。
http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx
"System.Xml.XPath命名空间中的XPathNavigator类是一个抽象类,它定义了一个光标模型,用于导航和编辑XML信息项作为XQuery 1.0和XPath 2.0数据模型的实例。
"