27.3 XPath和XSLT
XPath[1]是XML的查询语言,与SQL很类似,专门用于快速检索和查询XML文档,使用方便,功能强大,XPath也是XSLT技术的基础。因为使用到了XPath,因此要使用到System.Xml.XPath命名空间,这里将使用和之前不同的3个类,它们都属于System.Xml.XPath命名空间,如下:
❑XPathDocument:使用XPath数据模型提供XML文档的快速、只读、内存中的表示形式。
❑XPathNavigator:为定位和编辑XML数据提供游标模型。
❑XPathNodeIterator:在一组选中的节点上提供迭代器。
接下来,我们学习下如何使用这3个对象,其一般步骤为:
(1)首先,该项目要引用System.Xml和System.Xml.XPath名称空间。
(2)然后,声明XPathDocument、XPathNavigator以及XPathNodeIterator类型的对象,它们的作用分别为:保存XML文档、计算XPath表达式以及迭代选定的节点。
使用XPathDocument可以将XML文档读取到这样一个文档对象中,然后可以使用这个文档对象创建一个XPathNavigator类型的对象,最后该对象会返回一个XPathNodeIterator类型的迭代器对象,通过该迭代器对象就可以对当前节点集进行遍历操作了。要注意,之前返回的那个XPathNodeIterator对象并没有位于所选节点集的第一个节点上(这一点务必要注意)。必须调用XPathNodeIterator类的MoveNext方法,以将XPathNodeIterator对象定位到所选节点集的第一个节点上,如代码清单27-6所示。
代码清单27-6 使用XPath遍历XML文档
using System;
using System.Xml;
using System.Xml.XPath;
namespace ProgrammingCSharp4
{
class XmlHandleSample
{
public static void Main()
{
XPathNavigator nav;
XPathDocument doc;
XPathNodeIterator iter;
doc=new XPathDocument(@"c:\books.xml");
nav=doc.CreateNavigator();
iter=nav.Select("/books/book");
while(iter.MoveNext())
{
Console.WriteLine("——————————————");
LoadBook(iter.Current);
}
}
private static void LoadBook(XPathNavigator xPathNavigator)
{
XPathNodeIterator iter=xPathNavigator.SelectDescendants
(XPathNodeType.Element,false);
while(iter.MoveNext())
{
Console.WriteLine("{0}:{1}",iter.Current.Name,iter.Current.Value);
}
}
}
}
上述代码的运行结果为:
title:C Sharp 4.0程序设计
author:姜晓东
year:2010
title:哈利波特与魔法石
author:J K.Rowling
year:1977
请按任意键继续……
学习了XPath,我们接下来继续学习XSLT[2]。XSLT是一种将XML文档转换为其他文本文档的标记语言,它是建立在XML和XPath之上的国际标准。XPath之于XML,有点类似于CSS之于HTML,虽然这个例子可能不是十分恰当。只不过CSS的目标是定义页面的展现形式、风格,而XPath的目标则是将已有的XML文档转变为指定格式的目标文档。没有XSLT的时候,如果需要通过编程将XML文档中的数据抽取出来,并放到一个纯文本数据中时,需要写代码遍历XML文档对象构成的树状结构,对于每一个特定节点或特定层次的节点而输出不同的内容,这个过程比较繁杂,代码量也大,并且需要进行很多状态判断。而XSLT则使用一种简洁明了的标记语言实现了相同的逻辑。
XSLT的转换过程会涉及3个文本文档:第1个是要处理的原始XML文档;第2个就是XSLT样式表文档,该文档包含了XSLT代码,而XSLT代码本身就是XML格式,但使用了XML的名称空间;第3个就是XSLT处理后输出的文本文档,如图27-2所示。要注意的是,这里经过转换输出了纯文本文档,这个文档具体是什么格式完全由XSLT代码来决定,它可以是一个XML文档、一个HTML文档、一个文本文档,甚至可以是其他任意格式的字符串数据,等等。XSLT转换除了限制只能输出纯文本文档外,对输出文档的具体格式就没有任何限制。
图 27-2 XSLT示意图
接下来用一个例子来说明如何进行XSLT转换。这里使用的原始XML文档还是代码清单27-1,目标文档格式是HTML文档,具体形式就是展现一个数据表格,将书籍的数据展现出来。我们现在要做的,就是要提供一个转换所需的XSLT模板,如代码清单27-7所示。
代码清单27-7 XSLT模板
<xsl:stylesheet version='1.0'xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html'/>
<xsl:template match='/'>
<html>
<head>
<title>书籍列表</title>
</head>
<body>
<table border="1"width="50%">
<tr>
<td>书名</td>
<td align="center">作者</td>
<td align="center">出版年份</td>
</tr>
<xsl:for-each select="//book">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td align="center">
<xsl:value-of select="author"/>
</td>
<td align="center">
<xsl:value-of select="year"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
将上述XSLT模板保存为c:\books.xsl文件,万事俱备只欠东风,接下来编写代码执行这次转换,如代码清单27-8所示。
代码清单27-8 执行XSLT转换的C#代码
using System;
using System.Xml.Xsl;
namespace ProgrammingCSharp4
{
class XmlHandleSample
{
public static void Main()
{
try
{
XslTransform trans=new XslTransform();
trans.Load(@"c:\books.xsl");
trans.Transform(@"c:\books.xml",@"c:\books.html");
Console.WriteLine(“祝贺你!转换成功完成。”);
}
catch(System.Exception)
{
Console.WriteLine(“转换出错,请检查。”);
throw;
}
}
}
}
上述代码的执行结果如下:
❑显示“祝贺你!转换成功完成。”则代表转换成功;
❑在C盘根目录生成books.html文件,其内容如代码清单27-9所示。
代码清单27-9 执行完XSLT转换后生成的目标文件
<html>
<head>
<META http-equiv="Content-Type"content="text/html;charset=utf-8">
<title>书籍列表</title>
</head>
<body>
<table border="1"width="50%">
<tr>
<td>书名</td>
<td align="center">作者</td>
<td align="center">出版年份</td>
</tr>
<tr>
<td>C Sharp 4权威指南</td>
<td align="center">姜晓东</td>
<td align="center">2010</td>
</tr>
<tr>
<td>哈利波特与魔法石</td>
<td align="center">J K.Rowling</td>
<td align="center">1977</td>
</tr>
</table>
</body>
</html>
在浏览器中查看,如图27-3所示。
图 27-3 在Internet Explorer中查看生成的html文件
[1]XPath是W3C国际标准组织定义的用于在单个XML文档中快速检索和定位XML文档中节点的规范,它是跨平台的,若某软件支持XPath,那么一般情况下它也支持标准的XPath语法。因此无论是Java还是C#都支持相同的XPath语法。关于XPath的更详细用法,请参考http://www.w3.org/TR/xpath。
[2]更多关于XSLT的知识,请参阅http://www.w3.org/TR/xslt。