使用 XSL






4.95/5 (10投票s)
借助 XSL 进行转换
引言
XSL 转换快速、轻松,与任何其他服务器端或客户端方法相比,使用 XSL 转换文档类型变得毫不费力。因此,本文帮助您探索使用 XSL 可以实现多少功能。简而言之,创造力是 XSL 转换的唯一限制。
背景
我们经常需要将一个文档的内容转换为一种全新的文档类型,并具有不同的布局。例如,将博客文章提取出来作为新闻通讯发送。或者从 XML 文件的每个节点创建一个具有特定格式的文档。或者创建一个具有特定格式的 XML 文件,并将其更改为全新的格式。使用 XSL,我们可以做很多事情,而且它并不复杂。本文通过以下几点帮助您理解 XSL 转换:
- 理解内容 - 标签、关键字
- 实现简单转换
- 选择性读取内容
- 实现条件逻辑
- 施加样式
- 嵌入来自其他 XSL 资源的的代码
理解内容 - 标签、关键字等。
要开始 XSL 转换,我们首先需要创建一个 XSL 文件。首先,XSL 代表什么?嗯,它代表 EXtensible Stylesheet Language。因此,我们知道从技术上讲,XSL 文件是样式表,而且更多。现在,为了更好地理解,让我们继续在您的解决方案中添加一个 XSL 文件,使用 VS2012(这是我正在使用的)。当您打开它时,文件的内容如下所示(行号仅供参考,不会出现在实际代码中)。
1. <?xml version="1.0" encoding="utf-8"?>
2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3. xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
4. <xsl:output method="xml" indent="yes"/>
5.
6. <xsl:template match="@* | node()">
7. <xsl:copy>
8. <xsl:apply-templates select="@* | node()"/>
9. </xsl:copy>
10. </xsl:template>
11. </xsl:stylesheet>
在我们开始进行任何更改之前,让我们尝试理解每一行的含义。
- 第 1 行 - 这指定 XSL 文档是 XML 版本 1.0 类型,并将使用 utf-8 类型的编码。可以根据您的要求更改编码。
- 第 2 行 - 这一行标志着 XSL 文档的开始,我们看到它是一个样式表类型,并带有一些属性,这些属性是:
- version 1.0,这是当前的默认值。
xsmlns: xsl
- 将 XSL 的命名空间指定为默认命名空间。可以根据您的项目要求修改xmlns:xsl
的值。xmlns:msxsl
- 这指定将使用的默认脚本语言。其他可能的值可以是 C#、VB、JScript、JavaScript、VisualBasic 或 CSharp。exclude-result-prefixes
- 这有助于避免在结果元素中出现命名空间声明,这些命名空间已在样式表中声明并使用。这有助于在路径表达式或匹配模式中仅选择节点,或用于插入扩展元素。
- 第 4 行 - 指定转换后生成的文档将是 XML 类型,并且会进行缩进以便于阅读。这
xsl:output
的属性不止这两个。更详细的描述可以在 此处找到。 - 第 6 行 - 指定匹配将发生在哪些元素上。当前值表示应匹配所有节点。如果我们想匹配整个 XML 文档,可以使用 "/" 代替。常见匹配模式的简要概述可以在 此处找到。
- 第 7 行 - 此标签表示下一行中的选择将被复制并替换到此部分。
- 第 8 行 -
xsl:apply-template
标签确保仅处理通过select
属性提供匹配值的元素。 - 第 9 行 - 第 11 行 - 都是所有已打开标签的关闭标签。
所以,首先,我们现在知道 XSL 文件是什么样子,以及常用标签的含义和作用。
实现简单转换
下载 zip 文件Sample1 ,您会找到 2 个文件。一个是包含 CD 集合列表的 XML 文件,另一个是 XSL 文件,它将帮助我按照我想要的方式呈现 CD 集合。所以让我们看看 XSL 的内容。
<xsl:template match="/">
<html>
<body>
<h1>CD Collection</h1>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td>
<xsl:value-of select="catalog/cd/title[text()='Red']"/>
</td>
<td>
<xsl:value-of select="catalog/cd/artist[text()='The Communards']"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
- 模板匹配表示 XSL 应该与整个文档匹配。
html
部分标志着转换后将创建的文档的开始。body
需要有一个标题,并且应该以表格形式列出 CD 集合。- 有一个新的
xsl
标签称为xsl:value-of
。它返回所有与 select 属性中给出的条件匹配的文本。 select
属性有一个xpath
表达式。它表示匹配cd
节点的子节点中值为“Red
”的title
节点,而cd
节点又是 catalog 节点的子节点。
那么下一条表达式是什么意思?自己找出来。更改 XSL 文件并进行实验。但是要看到输出,您需要将 XML 文件与 XSL 相关联。那么如何做到呢?我知道 2 种方法:
- 打开 XML 文件,并在
xml
版本标签之后添加下面给出的行。<?xml-stylesheet type="text/xsl" href="CDCollection.xslt"?>
在这里
href
应该映射到 XSL 文件的实际路径,如果它们在 2 个不同的位置。现在在 Internet Explorer 中打开 XML 并查看输出。 - 另一种方法是将这两个文件添加到 VS2010 或其他版本的解决方案中。添加一个项目并引用这些文件。在您需要调用转换代码的地方,首先引用下面给出的 2 个命名空间。
- System.Xml
- System.Xml.Xsl
像这样声明一个转换对象
XslTransform cdXslTransform = new XslTransform();
接下来使用 load
方法
cdXslTransform.Load("CdCollection.xslt");
然后调用转换方法
cdXslTransform.Transform("CdCollection.xml", "FormattedCdCollection.xml");
新文件将生成在与CdCollection.xml相同的位置。
所以,您有样本文件可以开始,也有转换技术可供选择。现在,开始尝试吧。
选择性读取内容
现在,一旦您根据您的要求调整了文件,其中一些更改可能有效,而另一些则无效。所以让我们理解各种 select 表达式。在我们实际讨论不同的表达式之前,让我们理解 XSL 中的表达式是纯粹的 xpath
。所以,在这里,我们从表达式开始。
- 您想显示硬编码文本 - 无需使用 select。直接将其写在您希望它出现的地方。就像我们为标题所做的那样。例如:
<h1>CD Collection</h1>
- 您希望特定节点的文本出现,则执行以下操作:
<xsl:value-of>
- 这只会写入节点的文本。select
属性应将节点与特定值匹配。title[text()='Red']
- 您想复制匹配条件的整个元素 - 使用
<xsl:copy-of select="cd"/>
- 您想选择父节点,其子节点匹配某个值 - select 的表达式将是 -
<xsl:copy select="//cd[cd/title[text()='Red']"
- 您想选择一个元素的值并在以后使用它 -
<xsl:variable name="color" select="'red'" />
。但您需要记住,与在其他编程语言中的变量不同,分配给变量的值不能被重新分配。 - 您需要一个具有默认值的变量,该变量根据作用域具有不同的值 - 使用
<xsl:param>
。与<xsl:variable>
的语法相似,但有一个默认值并且可以被重新分配。 - 您需要选择一个属性值匹配字符串的元素 -
<xsl:value-of select="//cd[cd/title[@name='Red']"
,其中name
是title
节点的属性。 - 有很多您可能需要做的事情。已经内置了许多函数。可用的函数列表可以在 此处找到。
所以,现在您对该做什么以及如何继续试验有了更多的了解。
实现条件逻辑
现在,如果您一直在试验我们上面讨论的内容,您一定已经能够部分或全部地转换您的 XML。但 XSL 是另一种语言,我们总是希望使用一些条件逻辑。我们喜欢我们的 if
s 和 else
s 以及 for-each
和 while
。那么我们可以在 XSL 中做同样的事情吗?让我们看看 XSL 中我们可以做什么。
- 您想匹配单个条件或复制“
if
” - 使用<xsl:if>
。但不是select
属性,我们需要test
属性来匹配条件。所以语法是 -<xsl:if test="price > 10">
。 注意,因为 XSL 只是另一种 XML 文档,所以我们使用“>
”而不是通常的“>
”符号,并使用“<
”代替“<
”。 - 您想使用 AND 或 OR 连接多个条件 - AND 和 OR 都可以用来连接条件,但只能是小写,即“and”和“or”。例如 -
<xsl:if test="price > 10 and price < 20">
- 您想实现
switch
case 或if-else
或if-else if -else
- 使用<xsl:choose>
。语法将是
<xsl:choose>
<xsl:when test="price > 5">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
- 您想实现
for-each
- 使用<xsl:for-each>
,如下所示:
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
好了,现在您已经理解了条件逻辑和运算符。那么还在等什么?开始练习吧。只说一点,在您开始飞驰之前,请知道,与任何其他编程语言一样,在 XSL 中,您也可以将这些逻辑单独使用或与其他逻辑结合使用。
施加样式
所以在开始时,我们确实讨论过 XSL 是用于演示的。然后可以理解,我们希望用我们想要的样式来美化输出文档。那么我们可以在输出中使用样式吗?让我们尝试一些示例。
- 您想为具有特定值的元素分配样式
<xsl:attribute name="style">
<xsl:value-of select="'color: Red;'" />
</xsl:attribute>
- 您想在 xsl 文件中声明一个 CSS 类。使用
<xsl:attribute-set/>.
您可以添加一个类,然后按照以下方式添加其定义:
<xsl:attribute-set name="quote">
<xsl:attribute name="padding-start">2.5cm</xsl:attribute>
<xsl:attribute name="line-height">11pt</xsl:attribute>
</xsl:attribute-set>
最好将所有属性集声明在顶部,以便整个文档都有其作用域。
- 您想使用.css文件中声明的现有样式类 - 您可以通过引用它来在 XSL 文件中使用CdCollection.css,如下所示:
<link rel="stylesheet" type="text/css" href="CdCollection.css" />
只需将此行放在标题上方,您就会看到差异。尝试其他样式。要为 html
文档的正文添加样式。将下面的部分包含在.css文件中:
body{
}
所以也开始操作样式吧。
嵌入来自其他 XSL 资源的的代码
到目前为止,您将能够创建一个相当复杂的 XSL 文件来处理转换。但是仍然存在一个问题,我们是否需要为每次 XML 转换都创建一个 XSL 文件?如果我们为所有相似的文件集需要复制复杂的转换,难道不会很费力吗?嗯,别担心。编码世界并不那么糟糕。XSL 是可重用的,而且非常容易。那么我们如何做到呢?相当简单的方法是:
- 您可以改用
<xsl:import href="ResuableFormat.xsl"/>
import
标签引用外部资源,并将创建导入树。然后,您可以将导入的 XSL 所提供的任何功能用于您当前的 XSL 中。
- 您也可以使用
<xsl:include>
。它与<xsl:import>
的区别在于<xsl:include>
只能用作顶级元素。
所以,我们已经涵盖了 XSL 的大部分内容以及如何操作。希望这有所帮助。外面有很多资源。我只是试图将它们整合起来。我开始时引用的文章可以在 此处找到。示例 XML 和 XSL 是教程中可用示例的修改版本。另一个很棒的资源是 这个。请随时发表您的评论。