详解 xls xlst xml 一
1.XSLT 简介
XSLT 是Extensible Stylesheet Language Transformations的缩写
XSLT 用来将XML 文档转换到其它文档类型 通常是XHTML 型
XSLT 使用两个输入文件:
– 包含实际数据的XML 文档
– 包含要插入数据与XSLT 命令“架构”的XSL – 包含要插入数据与XSLT 命令架构的XSL文档
代码如下:
Hello.xml
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="hello.xslt"?>
<message>Hello,world!</message>
hello.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<h1>
<xsl:value-of select="message"/>
</h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
看效果,请右键“在浏览器中查看”。
查找message
<xsl:template match="/">
– 这个模板表示选择整个文档
你可以认为它表示选择XML树的根结点
在这个模板中:
– < xsl:value -of select="message"/>
表示选择message元素
– 还可以使用下面的Xpath 表达式:
./message
/message/text() ( text() 是一个XPath 函数)
./messa g e/text () g()
XSL 文档如下:
<xsl:template match="/">
<html><body>
<h1><xsl:value -of select =" message" / >
</body></html>
</xsl:template>
The <xsl:template match="/"> chooses the root
The <html><body> <h1> is written to the output file
The contents of message is written to the output file
The </h1> </body></html> is written to the output file
最后的结果:
<html><body>
<h1>Hello,world!</h1>
</body></html>
2.XSLT 是如何工作的
a)首先XML文档被读入内存当中并存储为棵结点树
b)<xsl:template match=“/”> 模板用来选择整个树的根结点
c)模板中的规则被用来进行结点的匹配从而改变XML 树的结构
d)如果还有其它模板,那么它们必须显示地从主模板中调用 如果还有其它模板,那么它们必须显示地从主模板中调用
e)XML 树中没有匹配的部分保持原来的状态不变
f)模板应用完成后,树被作为一个新的文本文档输出出来
3.XSLT 语法
a)xsl:value of
<xsl:value-of select="XPath expression "/>
selects the contents of an element and adds it to the output stream
– The select attribute is required
– Notice that xsl:value-of is not a container, hence it needs to end with a slash
Example :
<h1> <xsl:value-of select="message"/> </h1>
b)xsl:for-each
xsl:for-each is a kind of loop statement
The syntax is
< xsl:for-each select="XPath expression ">
Text to insert and rules to apply
</xsl:for-each>
Example: to select every book (//book) and make an
unordered list ( <ul> ) of their titles ( title ),
use:
< ul >
<xsl:for-each select="//book">
<li> <xsl:value-of select="title"/> </li>
</xsl: for-each >
</ul>
c)filter
You can filter (restrict) output by adding a criterion to the select attribute’s value:
<ul>
<xsl:for-each select="//book">
<li>
<xsl:value-of select="title[../author= 'Refactor' ]"/>
</li>
</xsl:for-each>
</ul>
This will select book titles by Refactor
learn more:
Here is the filter we just used:
<xsl:value-of select="title[../author='Refactor']"/>
authoris a sibling of title , so from title we have to go up to its parent,
book, then back down to author
This filter requires a quote within a quote,
so we need both single quotes and double quotes
Legal filter operators are:
= != < >
-Numbers should be quoted,but apparently don't have to be
d)xsl:if
xsl:if allows us to include content if a given condition(in the test attribute) is ture
Example:
<xsl:for-each select="//book">
<xsl:if test="author='Refactor'">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:if>
</xsl:for-each>
e)xsl:choose
the xsl:choose...xsl:when...xsl:otherwise construct is XML's equivalent of C#’s switch ...
case default statement case ... default statement
The syntax is:
<xsl:choose >
<xsl:when test="some condition">
... some code ...
</xsl:when>
<xsl:otherwise>
... some code ...
</xsl:otherwise>
</xsl:choose>
f)xsl:sort
you can place an xsl:sort inside an xsl:for-eash
The attribute of the sort tells what field to sort on
Example:
<ul>
<xsl:for-each select=" //book">
<xsl:sort select="author"/>
<li> <xsl:value-of select="title"/> by
<xsl:value-of select="author"/> </li>
</xsl:for-each>
</ul>
– This example creates a list of titles and authors sorted by author
g)xsl:text
xsl:text helps deal with two common problems:
-XSL isn't very careful with whitespace in the document
This doesn’t matter much for HTML , which collapses all whitespace anyway
(though the HTML source may look ugly)
<xsl:text> gives you much better control over whitespace;
it acts like the <pre> element in HTML
– Since XML defines only five entities, you cannot readily put other entities
(such as ) in your XSL
&nbsp;almost works, but is visible on the page
Here’s the secret formula for entities
h)xsl:apply- templates
The <xsl:apply-templates> element applies a template rule to
the current element or to the current element’s child nodes
If we add a select attribute, it applies the
template rule only to the child that matches
If we have multiple < xsl:apply -templates > elements with select attributes,
the child nodes are processed in the same order as the are processed
in the same order as the <xsl:apply-templates> elements
4.什么时候忽略模板?
Templates aren’t used unless they are applied
– Exception: Processing always starts with select="/"
– If it didn’t, nothing would ever happen
If your templates are ignored ,you probably forgot to apply them
If you apply a template to an element that has child elements, templates are not automatically
applied to those child elements applied to those child elements
5.将模板应用到子元素
<book >
<title>XML</title>
<author>Refactor</author>
</book>
<xsl:template match="/">
<html> <head ></head> <body>
<b><xsl:value-of select="/book/title"/></b>
<xsl:apply-templates select="/book/author"/>
</body> </html>
</xsl:template>
<xsl:template match "/book/author">
by <i><xsl:value-of select="."/></i>
</xsl:template>
6.调用命名模板
You can name a template, then call it, similar to the way you would
call a method in C#
The named template:
<xsl:template name=" myTemplateName">
...body of template...
</xsl:template >
A call to the template:
<xsl:call-template name="myTemplateName"/>
Or:
<xsl:call-template name="myTemplateName">
...p arameters... p
</xsl:call-template>
7.使用参数应用模板
Parameters, if present,are included in the content of xsl:template,
but are the only content of xsl:call-template
Example call:
<xsl:call-template name="doOneType">
<xsl:with-param name="header" select="'Lectures'"/>
<xsl:with-param name="nodes" select="//lecture"/>
</xsl:call-template>
Example template:
<xsl:template name=" doOneType"> xsl:template name doOneType
<xsl:param name="header"/>
<xsl:param name="nodes"/>
...template body ...refer to parameters as "$header" and "$nodes"
</xsl:template>
Parameters are matched up by name, not by position
8..NET 中实现XSLT
a)使用XslCompiledTransform类
XslCompiledTransform 类是.NET Framework XSLT 处理器。
此类用于编译样式表并执行 XSLT 转换
b)XslCompiledTransform类的输入
IXPathNavigable 接口
–XmlNode类基于W3C文档对象模型(DOM) 并具有编辑功能。
–XPathDocument类是基于XPath 数据模型的只读数据存储。
XPathDocument是XSLT 处理建议使用的类。与XmlNode类相比,此
类的性能更强。
XmlReader 对象
– Transform 方法从XmlReader的当前节点及其所有子节点加载。这样,
可以使用文档的一部分作为上下文文档使用。Transform方法返回后,
XmlReader将位于上下文文档结尾之后的下一个节点上。如果已到达文
档结尾,XmlReader将位于文件结尾(EOF) 。
字符串URI
– 还可以将源文档URI 指定为XSLT 输入。XmlResolver用于解析URI。
可以指定要使用的XmlResolver,方法是将其传递给Transform方法。
如果未指定XmlResolver,Transform方法将使用没有凭据的默认
XmlUrlResolver 。
c)XslCompiledTransform类的输出
XmlWriter
– XmlWriter 类输出XML 流或文件。可以使用XmlWriterSettings类指定
XmlWriter 对象上要支持的功能,包括输出选项。
XmlWriter 类是System.Xml 框架必不可少的一个部分。
使用此输出类型可以将输出结果通过管道发送给另一个XML 进程。
String
– 使用此输出类型可以指定输出文件的 URI。
Stream
– 流是字节序列的抽象,例如文件、输入/输出设备、进程中通信管道或 TCP/IP 套
接字。Stream 类及其派生类提供这些不同类型的输入和输出的通用视图,使程序
与操作系统基础设备的具体细节相隔离。
– 使用此输出类型可以将数据发送到 FileStream 、MemoryStream 或输出流
(Response.OutputStream) 。
TextWriter
– TextWriter 输出序列字符。此输出类型在StringWriter 和StreamWriter类中实
现,分别将字符输出到字符串或流。 如果希望输出到字符串,请使用此输出类型。
9.进行转换
//Load an XPathDocument
XPathDocument doc = new XPathDocument("books.xml");
// Locate the node fragment
XPathNavigator nav = doc.CreateNavigator();
XPathNavigator myBook = nav.SelectSingleNode("descendant::book[@ISBN = '0-201-63361-2']");
//Create a new object with just the node fragment.
XmlReader reader = myBook.ReadSubtree();
reader.MoveToContent();
//Load the style sheet.
XslCompiledTransform xlst= new XslCompiledTransform() ;
xslt.Load("single.xsl");
// Transform the node fragment
xslt.Transform(reader, XmlWriter.Create(Console.Out, xslt.OutputSettings))
10.下节以实例为主.
未完待续,敬请期待...