在.Net framework中有个XslCompiledTransform类,它只能处理XSLT1.0的样式表,微软目前官方也不准备提供对2.0的支持。然而这并不是说,我们就不能在.Net中使用XSLT2.0的新特性,通过第三方提供的类库,可以实现同样的目的。
XSLT2.0比起1.0更强大,提供了更方便的方法,以下是2.0中的几个主要改进:
- 支持正则表达式
- 提供更多的函数处理时间,像获取当前时间,格式化时间
- 用户定义函数,xsl:function
- 字符串比较
tokenize()和matches()方法- for … in … return
- next-match
- as 属性 ,<xsl:variable name="i" as="xs:integer" select="@size"/> 或 <xsl:function name="str:reverse" as="xs:string">
查看所有的方法和新的特性都去网站W3C,w3schools上列出了所有函数。
目前知名的第三方控件,包括
Saxon , 这个可以用于Java和.Net,而且它提供了开源和商业两个不同的版本。在这个例子中, 我们用Saxon .NET API来说明如何使用XSLT2.0。
XML源文档:
<?xml version="1.0" encoding="utf-8"?> <cities> <city name="Milano" country="Italia" pop="1307495" /> <city name="Paris" country="France" pop="2220140" /> <city name="Bordeaux" country="France" pop="719489" /> <city name="München" country="Deutschland" pop="1260391" /> <city name="Lyon" country="France" pop="474946" /> <city name="Venezia" country="Italia" pop="270801" /> <city name="Delft" country="Holland" pop="94512" /> <city name="Rotterdam" country="Holland" pop="607460" /> </cities> |
预期输出:
![]() |
XSLT 文件:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="iso-8859-1" />
<xsl:template match="/">
<html>
<head>
<title>Cities</title>
</head>
<body>
Generated at
<xsl:value-of select="format-dateTime(current-dateTime(), '[D].[M].[Y] [H]:[m]:[s]' )" />
<br />
<table style="border : 1px solid #000;">
<thead>
<tr>
<th>Position</th>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="cities/city" group-by="@country">
<xsl:sort select="sum(current-group()/@pop)" data-type="number" order="descending" />
<tr>
<td>
<xsl:value-of select="position()" />
</td>
<td>
<xsl:value-of select="@country" />
</td>
<td>
<xsl:value-of select="current-group()/@name" separator=", " />
</td>
<td>
<xsl:value-of select="sum(current-group()/@pop)" />
</td>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
|
这个XSLT包含单个模板,它的规则就是将XML内容转化成HTML格式。
在XML中, 包含一组城市列表,在输出的HTML中,会对城市分组,然后根据人口数的多少排序。在上面的XSLT中,我们用xsl:for-each-group指令对城市分组,在1.0中我们也可以实现分组功能,只是实现起来更复杂,2.0直接提供了内置的支持。另外一个有用的函数就是current-dateTime()和format-dateTime()方法,对于时间相关的操作,这两个方法非常有用。
.Net 代码:
namespace Saxon
{
internal class Program
{
private static void Main()
{
const string xmlFile = @"..\..\cities.xml";
const string xsltFile = @"..\..\cities.xslt";
const string outFile = @"..\..\cities_grouped.html";
try
{
using (XmlReader xml = XmlReader.Create(xmlFile))
using (XmlReader xslt = XmlReader.Create(xsltFile))
{
// Create a Processor instance
var processor = new Processor();
// Load the source document
XdmNode input = processor.NewDocumentBuilder().
Build(xml);
// Create a transformer for the stylesheet
XsltTransformer transformer = processor.NewXsltCompiler().
Compile(xslt).Load();
// Set the root node of the source document to be the initial context node
transformer.InitialContextNode = input;
// Create a serializer
var serializer = new Serializer();
serializer.SetOutputStream(new FileStream(outFile, FileMode.Create, FileAccess.Write));
// Transform the source XML
transformer.Run(serializer);
Console.WriteLine("Output written to " + outFile + Environment.NewLine);
}
}
catch (Exception e)
{
ConsoleColor currentConsoleColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("oops : " + e.Message);
Console.ForegroundColor = currentConsoleColor;
}
Console.Write("Press any key to exit ...");
Console.ReadKey();
}
}
}
|
其它第三方控件:
XQSharp, AltovaXML 这些类库都可以.Net环境中使用。
源代码:
https://files.cnblogs.com/zhaojin/Saxon.zip


浙公网安备 33010602011771号