XML (转换)

       XSL(Extensible Stylesheet Language,可扩展样式表语言)是一种用于创建样式表的基于 XML 的语言。样式表(转换)是特殊的文档,可以在 XSLT 处理器的帮助下把 XML 文档转换成其它文档。(不要和 CSS 混淆,CSS 是用来格式化 HTML 的标准)。

 

基本的样式表

       XSL 是一个复杂的标准,事实上,它可以被看做是一个真正的语言,因为它有逻辑、循环结构等。

       执行任何转换前,需要创建一个定义如何应用转换的 XSL 样式表。把 DVD 列表转换为 HTML 时,将用到下面所示的简单样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates select="DvdList/DVD" />
      </body>
    </html>
  </xsl:template>
 
  <xsl:template match="DVD">
    <hr />
    <h3>
      <u>
        <xsl:value-of select="Title"/>
      </u>
    </h3>
    <b>Price: </b>
    <xsl:value-of select="Price"/>
    <br />
    <b>Director: </b>
    <xsl:value-of select="Director"/>
    <br />
    <xsl:apply-templates select="Starring" />
  </xsl:template>
 
  <xsl:template match="Starring">
    <b>Starring</b>
    <br />
    <xsl:apply-templates select="Star" />
  </xsl:template>
 
  <xsl:template match="Star">
    <li>
      <xsl:value-of select="."/>
    </li>
  </xsl:template>
 
</xsl:stylesheet>

       所有的 XSL 文件里都有一个根元素 <stylesheet>,<stylesheet>元素可包括一个或多个模版(这个示例有 4 个)。第一个<template>元素匹配根元素,找到它后,它开始输出 HTML 页面所必需的标签,接着它使用 <apply-templates> 命令分解并处理所有 <DVD> 元素,它们是 <DvdList>的子元素,如下所示:

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates select="DvdList/DVD" />
    </body>
  </html>
</xsl:template>

       每匹配一个 <DVD> 标签,就添加一条水平线并创建一个标题。<Title>、<Price>、<Director>标签中的信息由 <value-of> 命令解析并写到页面上。

<xsl:template match="DVD">
  <hr /><h3><u><xsl:value-of select="Title"/></u></h3>
  <b>Price: </b><xsl:value-of select="Price"/><br />
  <b>Director: </b><xsl:value-of select="Director"/><br />
  <xsl:apply-templates select="Starring" />
</xsl:template>

 

 

使用 XslCompiledTransform

       使用样式表以及 XslCompiledTransform 类(System.Xml.Xsl 命名空间中)可以把 DVD 列表转换为格式化的 HTML 。下面是执行转换的代码,同时把结果保存到一个新的文件里:

protected void Page_Load(object sender, EventArgs e)
{
    string xslFile = Server.MapPath("DvdList.xslt");
    string xmlFile = Server.MapPath("DvdList.xml");
    string htmlFile = Server.MapPath("DvdList.htm");
 
    XslCompiledTransform transform = new XslCompiledTransform();
    transform.Load(xslFile);
    transform.Transform(xmlFile, htmlFile);
}

 

       在一个动态的 Web 应用程序里,你会希望转换 XML 文件后直接返回结果代码,而不是生成一个 HTML 文件。要做到这点,需要为源 XML 文件创建 XPathNavigator ,然后可以把这个 XPathNavigator 传递给 Transform()方法,并获取任意流对象中的结果:

protected void Page_Load(object sender, EventArgs e)
{
    // Create an XPathNavigator.
    string xmlFile = Server.MapPath("DvdList.xml");
    XPathDocument xdoc = new XPathDocument(new XmlTextReader(xmlFile));
    XPathNavigator xnav = xdoc.CreateNavigator();
 
    // Transform the XML.
    MemoryStream ms = new MemoryStream();
    XsltArgumentList args = new XsltArgumentList();
    XslCompiledTransform transform = new XslCompiledTransform();
    string xslFile = Server.MapPath("DvdList.xslt");
    transform.Load(xslFile);
    transform.Transform(xnav, args, ms);
 
    // 一旦拥有了某个 MemoryStream 中的结果,就可以创建 StreamReader 来获取
    StreamReader r = new StreamReader(ms);
    ms.Position = 0;
    Response.Write(r.ReadToEnd());
    r.Close();       
}

image

 

 

使用 XML 控件

       有时候你可能希望把带有其他内容的转换后的 HTML 输出和 Web 控件组合在一起,XML 控件在页面独立的部分显示 XSL 转换后的结果:

<asp:Xml ID="Xml1" runat="server" DocumentSource="DvdList.xml" 
    TransformSource="DvdList.xslt"></asp:Xml>

       这个示例最好的一点是只需设置 2 个属性而不需要手工书写任何代码。

 

       不必为了使用 XML 控件而使用独立的文件。

       你也可以在编码中把 XmlDocument 对象赋给 Document 属性,或者给 DocumentContent 属性赋一个包含 XML 内容的字符串,而不是使用 DocumentSource 属性。类似的,你可以给 Transform 属性赋一个 XslTransform 对象值来提供 XSLT 信息。

       如果需要编程来支持 XML 和 XSLT 数据(从数据库记录中抽取数据),这些技术将非常有用。

 

 

使用 LINQ to XML 转换 XML

       XSL 并不是改变 XML 格式的唯一方式(过去它是唯一实际可行的办法),但今天,LINQ to XML 提供了一个富有竞争力的选择。要使用 LINQ to XML 进行转换,你需要一个运用投影的 LINQ 表达式。技巧在于投影必须返回一个 XElement 而不是匿名类型。

string xmlFile = Server.MapPath("DvdList.xml");
XDocument doc = XDocument.Load(xmlFile);
 
XDocument newDoc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("Movies",
        from DVD in doc.Descendants("DVD")
        where (int)DVD.Attribute("ID") < 3
        select new XElement[]
        {
            new XElement ("Moive",
                new XAttribute("name", (string)DVD.Element("Title")),
                DVD.Descendants("Star")
            )
        }
    )
);
 
string newFile = Server.MapPath("MovieList.xml");
newDoc.Save(newFile);
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Movies>
  <Moive name="The Matrix">
    <Star>Keanu Reeves</Star>
    <Star>Laurence Fishburne</Star>
  </Moive>
  <Moive name="Forrest Gump">
    <Star>Tom Hanks</Star>
    <Star>Robin Wright</Star>
  </Moive>
</Movies>

       基于 LINQ 转换的语法通常要比使用 XSL 样式表的转换更容易理解,并且更加精确你也可以很方便的替换为另一个 IEnumable<T>的集合,包括 LINQ to Entities 获得的结果集,然后随意打包成另一种格式的 XML 文档。

posted on 2012-08-27 15:45  SkySoot  阅读(2422)  评论(0编辑  收藏  举报

导航