专注

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在.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">

查看所有的方法和新的特性都去网站W3Cw3schools上列出了所有函数。

目前知名的第三方控件,包括

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>

 

预期输出:

image

 

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();
        }
    }
} 

 

其它第三方控件:

XQSharpAltovaXML 这些类库都可以.Net环境中使用。

源代码:

https://files.cnblogs.com/zhaojin/Saxon.zip

posted on 2012-03-13 10:45  中金黄金  阅读(619)  评论(1编辑  收藏  举报