[转] XSLT,注释和处理指令
时间:2007-12-25 来源:Z_Aaron
今天刚申请了这个blog,看到可以通过xslt自定义页面样式,于是,为了把blog的风格修改成自己想要的样子,开始查一些有关XSLT的资料,收集在这里,以便学习。
以下内容为转载:
-----------------------------------------------
XSLT,注释和处理指令(1) 作者:Bob DUCharme
发表时间:2000年9月13日
原文链接:XML.com/pub/a/2000/09/13/xslt/index.html">http://www.xml.com/pub/a/2000/09/13/xslt/index.html
译者:dlee
翻译时间:2001年6月16日
XSLT 包括了内建的用来从一个源树到一个结果树拷贝文本的模板规则。然而注释和处理指令却被遗漏在外面,除非你另外指定,否则一个 XSLT 处理器将忽略它们。你也可以另外指定,这个能力使你能够访问它们所保存的潜在的有价值信息。
你也可以添加注释和处理指令到你的输出,这让你可以保存除此以外无法适合你的文档的信息。这种既能读取也能写入注释和处理指令的能力让你可以从你的源树到你的输入树拷贝注释和处理指令,甚至将它们转换为元素。
在你的输出中的注释
使用 xsl:comment 元素添加注释节点到你的结果树。使用方法很简单:将你的注释的文本放在它的开始和结束标记之间。例如,一个 XSLT 处理器应用下列的模板到一个 poem 元素。
<xsl:template match="poem">
<html>
<xsl:comment> Created by FabAutoDocGen release 3 </xsl:comment>
<xsl:apply-templates/>
</html>
</xsl:template>
将添加下列的注释到结果树的 html 开始标记和其内容之间。
<!-- Created by FabAutoDocGen release 3 -->
注意 xsl:comment 开始标记后和结束标记前的空格保持实际的注释成为输出,而不是与开始和结束注释的连字符 (-) 碰在一起。
再说一下连字符,在你的输出注释中的一对连字符和在你的注释结尾的单个连字符,就象下面显示的一样,属于技术错误。
<xsl:template match="poem">
<html>
<xsl:comment> Created by FabAutoDocGen -- rel. 3 -</xsl:comment>
<xsl:apply-templates/>
</html>
</xsl:template>
对于一个 XSLT 处理器从这个错误中恢复是非常容易的。按照 XSLT 规范,它可以插入一个空格在两个连续的连字符之间和插入一个空格在结束一个注释的连字符之后,以使得注释合法,就象这样
<html>
<!-- Created by the FabAutoDocGen system - - rel. 3 - -->
尽管一些处理器会为你纠正这个错误,依靠处理器仍然不是一个好的主意,最好是指定合法的注释文本作为你的样式单的 xsl:comment 元素的内容。
注意,如果一个 xsl:comment 元素是一个顶级元素 -- 也就是说,是一个 xsl:stylesheet 元素的子元素 -- 一个 XSLT 处理器将忽略它。它必须是可以添加什么到结果树中的一个元素的子元素。在上面的例子中,xsl:comment 元素是一个 xsl:template 元素的子元素。
通过将一个模板规则的 xsl:apply-templates 或 xsl:value-of 元素放到 xsl:comment 的开始和结束标记之间,一个样式单可以转换由这些元素表示的源树内容到一个输出注释中。例如,下面的模板规则转换一个就象是在 W3C Schemas 中找到的 document 元素到输出的 XML 1.0 的注释。
<xsl:template match="documentation">
<xsl:comment><xsl:apply-templates/></xsl:comment>
</xsl:template>
它将转换这个
<documentation>The following is a revision.</documentation>
成为这样
<!--The following is a revision.-->
从你的源数中读取和使用注释
一个有 comment() 函数作为它的 match 属性的样式单模板选择了源树中所有的注释。下面的模板拷贝注释到目标树。
<xsl:template match="comment()">
<xsl:comment><xsl:value-of select="."/></xsl:comment>
</xsl:template>
(有一个很小的机会,注释将甚至不会作用于源树。 XML 解析器并不要求传递注释给应用程序 -- 在这种情况下,XSLT 处理器 -- 如果你没有看到它们 (注释 -- 译者注) 被显示的话,请与你的 XSLT 处理器一起使用另一个不同的 XML 解析器。)
一旦你已经从源树中读到了注释,你不必将它们也输出为注释。使用一个字面结果元素包装 comment() 模板的 xsl:value-of 元素 (或将它放在一个 xsl:element 元素之中) 使你可以将注释转换为元素。例如,下面的样式单中的第一个模板
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="comment()">
<doc><xsl:value-of select="."/></doc>
</xsl:template>
<xsl:template match="verse">
<p><xsl:apply-templates/></p>
</xsl:template>
</xsl:stylesheet>
转换这个文档中的注释
<!-- Poem starts here. -->
<verse>Of Man's First Disobedience, and the Fruit</verse>
<!-- Poem ends here. -->
到这里显示的 doc 元素
<doc> Poem starts here. </doc>
<p>Of Man's First Disobedience, and the Fruit</p>
<doc> Poem ends here. </doc>
处理指令
一个与特定的 XML 或 HTML 文档共同使用的样式单的设计是对 XML 处理指令最普通的用法。这仅仅是它们传递无法适应一个文档正常结构的信息的能力的一个例子。能够使用一个 XSLT 样式单读取和写入这些信息给了你的应用程序更加强大的与其它程序通信的能力。
输出处理指令
使用 xsl:processing-instruction 元素添加处理指令节点到你的结果树。在一个 name 属性中指定处理指令的目标 (用 XML 规范中的话来说,是 “用来标识指令指向的应用程序”) ,并放置其它的处理指令内容在 xsl:processing-instruction 元素的开始和结束标记之间。
因为一个 XML 处理指令结束于两个字符 ?> ,你的处理指令的内容不能包括一个问号直接跟一个大于号。
下面的例子
<xsl:template match="article">
<xsl:processing-instruction name="xml-stylesheet">
<xsl:text>href="headlines.CSS技巧">CSS" type="text/css"</xsl:text>
</xsl:processing-instruction>
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
当 XSLT 处理器在源树中找到一个 article 元素时,将添加这个处理指令
<?xml-stylesheet href="headlines.css" type="text/css">
到结果树的 html 元素之前。
关于这个例子有两件特殊的事:
<xsl:template match="stylesheetFile">
<xsl:processing-instruction name="xml-stylesheet">
href="<xsl:value-of select='.'/>"
type="<xsl:value-of select='@type'/>"
</xsl:processing-instruction>
</xsl:template>
将这个 stylesheetFile 元素
<stylesheetFile type="text/css">headlines.css</stylesheetFile>
转换为这个处理指令。
<?xml-stylesheet href="headlines.css" type="text/css" ?>
它使用匹配的 stylesheetFile 元素节点的内容作为在结果树的处理指令中的 href 参数,使用 stylesheetFile 元素的 type 属性的值作为处理指令 type 参数。 (模板没有使用 xsl:text 元素在其内容之外以避免换行出现在结束的处理指令中,因为它不能 -- 内容包括两个 xsl:value-of 元素,而一个 xsl:text 元素不能够有任何子元素。结果的处理指令仍然是完全合法的 XML)
与 xsl:comment 元素类似,一个 xsl:processing-instruction 元素不能是一个顶级元素 -- 如果它是一个 xsl:stylesheet 元素的子元素,一个 XSLT 处理器将忽略它。就象上面的例子所显示的那样,它应该是一个可以添加节点到结果树中的元素 (在这个例子中,即xsl:template) 的子元素。
从你的源树中读取和使用处理指令
一个 XSLT 处理器对于在源树中的处理指令的缺省处理是忽略它们。使用 processing-instruction() 函数,你的样式单可以找到处理指令并添加它们到结果树中。例如,这个模板拷贝所有的处理指令到输出而不做任何改变。
<xsl:template match="processing-instruction()">
<xsl:copy/>
</xsl:template>
XSLT 也使你可以通过必须存在于每个处理指令中的目标的值选择处理指令。与 XSLT 使用 xsl:value-of 元素取出处理器指令内容的能力一起,你可以通过使用指定的处理指令目标利用这个能力转换处理指令到它们自己的元素中。
例如,下列的 XML 文档摘录中有两个处理指令和不同的处理指令目标:xml-stylesheet 和 smellPlugIn。
<?xml-stylesheet href="headlines.css" type="text/css"?>
<verse>And hazard in the Glorious Enterprise</verse>
<?smellPlugIn scent="newCar" duration="12secs"?>
除了转换上面的 verse 元素到一个 p 元素以外,下面的模板规则将转换 xml-stylesheet 处理指令到一个 stylesheet 元素,转换 smellPlugIn 处理指令到一个 smellPlugIn 元素。
<xsl:template match="processing-instruction('xml-stylesheet')">
<stylesheet><xsl:value-of select="."/></stylesheet>
</xsl:template>
<xsl:template match="processing-instruction('smellPlugIn')">
<smellData><xsl:value-of select="."/></smellData>
</xsl:template>
<xsl:template match="verse">
<p><xsl:apply-templates/></p>
</xsl:template>
上面的模板应用例子的输入添加下列内容到结果树中:
<stylesheet>href="headlines.css" type="text/css"</stylesheet>
<p>And hazard in the Glorious Enterprise</p>
<smellData>scent="newCar" duration="12secs"</smellData>
使用我们在这里已经看到的专用的 XSLT 元素和函数,你可以充份利用注释和处理指令可以添加到你的输入和输出文档中的全部灵活性。毕竟有的时候 XML 文档并不仅仅是元素和属性。
以下内容为转载:
-----------------------------------------------
XSLT,注释和处理指令(1) 作者:Bob DUCharme
发表时间:2000年9月13日
原文链接:XML.com/pub/a/2000/09/13/xslt/index.html">http://www.xml.com/pub/a/2000/09/13/xslt/index.html
译者:dlee
翻译时间:2001年6月16日
XSLT 包括了内建的用来从一个源树到一个结果树拷贝文本的模板规则。然而注释和处理指令却被遗漏在外面,除非你另外指定,否则一个 XSLT 处理器将忽略它们。你也可以另外指定,这个能力使你能够访问它们所保存的潜在的有价值信息。
你也可以添加注释和处理指令到你的输出,这让你可以保存除此以外无法适合你的文档的信息。这种既能读取也能写入注释和处理指令的能力让你可以从你的源树到你的输入树拷贝注释和处理指令,甚至将它们转换为元素。
在你的输出中的注释
使用 xsl:comment 元素添加注释节点到你的结果树。使用方法很简单:将你的注释的文本放在它的开始和结束标记之间。例如,一个 XSLT 处理器应用下列的模板到一个 poem 元素。
<xsl:template match="poem">
<html>
<xsl:comment> Created by FabAutoDocGen release 3 </xsl:comment>
<xsl:apply-templates/>
</html>
</xsl:template>
将添加下列的注释到结果树的 html 开始标记和其内容之间。
<!-- Created by FabAutoDocGen release 3 -->
注意 xsl:comment 开始标记后和结束标记前的空格保持实际的注释成为输出,而不是与开始和结束注释的连字符 (-) 碰在一起。
再说一下连字符,在你的输出注释中的一对连字符和在你的注释结尾的单个连字符,就象下面显示的一样,属于技术错误。
<xsl:template match="poem">
<html>
<xsl:comment> Created by FabAutoDocGen -- rel. 3 -</xsl:comment>
<xsl:apply-templates/>
</html>
</xsl:template>
对于一个 XSLT 处理器从这个错误中恢复是非常容易的。按照 XSLT 规范,它可以插入一个空格在两个连续的连字符之间和插入一个空格在结束一个注释的连字符之后,以使得注释合法,就象这样
<html>
<!-- Created by the FabAutoDocGen system - - rel. 3 - -->
尽管一些处理器会为你纠正这个错误,依靠处理器仍然不是一个好的主意,最好是指定合法的注释文本作为你的样式单的 xsl:comment 元素的内容。
注意,如果一个 xsl:comment 元素是一个顶级元素 -- 也就是说,是一个 xsl:stylesheet 元素的子元素 -- 一个 XSLT 处理器将忽略它。它必须是可以添加什么到结果树中的一个元素的子元素。在上面的例子中,xsl:comment 元素是一个 xsl:template 元素的子元素。
通过将一个模板规则的 xsl:apply-templates 或 xsl:value-of 元素放到 xsl:comment 的开始和结束标记之间,一个样式单可以转换由这些元素表示的源树内容到一个输出注释中。例如,下面的模板规则转换一个就象是在 W3C Schemas 中找到的 document 元素到输出的 XML 1.0 的注释。
<xsl:template match="documentation">
<xsl:comment><xsl:apply-templates/></xsl:comment>
</xsl:template>
它将转换这个
<documentation>The following is a revision.</documentation>
成为这样
<!--The following is a revision.-->
从你的源数中读取和使用注释
一个有 comment() 函数作为它的 match 属性的样式单模板选择了源树中所有的注释。下面的模板拷贝注释到目标树。
<xsl:template match="comment()">
<xsl:comment><xsl:value-of select="."/></xsl:comment>
</xsl:template>
(有一个很小的机会,注释将甚至不会作用于源树。 XML 解析器并不要求传递注释给应用程序 -- 在这种情况下,XSLT 处理器 -- 如果你没有看到它们 (注释 -- 译者注) 被显示的话,请与你的 XSLT 处理器一起使用另一个不同的 XML 解析器。)
一旦你已经从源树中读到了注释,你不必将它们也输出为注释。使用一个字面结果元素包装 comment() 模板的 xsl:value-of 元素 (或将它放在一个 xsl:element 元素之中) 使你可以将注释转换为元素。例如,下面的样式单中的第一个模板
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="comment()">
<doc><xsl:value-of select="."/></doc>
</xsl:template>
<xsl:template match="verse">
<p><xsl:apply-templates/></p>
</xsl:template>
</xsl:stylesheet>
转换这个文档中的注释
<!-- Poem starts here. -->
<verse>Of Man's First Disobedience, and the Fruit</verse>
<!-- Poem ends here. -->
到这里显示的 doc 元素
<doc> Poem starts here. </doc>
<p>Of Man's First Disobedience, and the Fruit</p>
<doc> Poem ends here. </doc>
处理指令
一个与特定的 XML 或 HTML 文档共同使用的样式单的设计是对 XML 处理指令最普通的用法。这仅仅是它们传递无法适应一个文档正常结构的信息的能力的一个例子。能够使用一个 XSLT 样式单读取和写入这些信息给了你的应用程序更加强大的与其它程序通信的能力。
输出处理指令
使用 xsl:processing-instruction 元素添加处理指令节点到你的结果树。在一个 name 属性中指定处理指令的目标 (用 XML 规范中的话来说,是 “用来标识指令指向的应用程序”) ,并放置其它的处理指令内容在 xsl:processing-instruction 元素的开始和结束标记之间。
因为一个 XML 处理指令结束于两个字符 ?> ,你的处理指令的内容不能包括一个问号直接跟一个大于号。
下面的例子
<xsl:template match="article">
<xsl:processing-instruction name="xml-stylesheet">
<xsl:text>href="headlines.CSS技巧">CSS" type="text/css"</xsl:text>
</xsl:processing-instruction>
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
当 XSLT 处理器在源树中找到一个 article 元素时,将添加这个处理指令
<?xml-stylesheet href="headlines.css" type="text/css">
到结果树的 html 元素之前。
关于这个例子有两件特殊的事:
- 这个例子在没有 xsl:text 元素包围新的处理指令的内容时仍然工作,但是那样在文本任何一边的回车将被包括在输出中,将处理指令分割成三行。(包括在结果树中的字符数据的下一个回车,其它的回车) 一个有回车在其中的处理指令仍然是完全合法的。
- 添加在结果树中的处理指令结束于 ">" 而不是象大多数 XML 的处理指令一样结束于 "?>" 。XSLT 处理器知道样式单创建了一个 HTML 文档,因为结果树的 document 元素叫做 "html",于是它创建了一个 HTML 风格的处理指令。如果结果树的 document 元素不是 "html" (并且如果你没有使用一个带有 "html" 值的一个 xsl:output 元素的 method 属性明确地告诉它创建一个 HTML 风格的输出),那么新的处理指令将结束于 "?>" 。
<xsl:template match="stylesheetFile">
<xsl:processing-instruction name="xml-stylesheet">
href="<xsl:value-of select='.'/>"
type="<xsl:value-of select='@type'/>"
</xsl:processing-instruction>
</xsl:template>
将这个 stylesheetFile 元素
<stylesheetFile type="text/css">headlines.css</stylesheetFile>
转换为这个处理指令。
<?xml-stylesheet href="headlines.css" type="text/css" ?>
它使用匹配的 stylesheetFile 元素节点的内容作为在结果树的处理指令中的 href 参数,使用 stylesheetFile 元素的 type 属性的值作为处理指令 type 参数。 (模板没有使用 xsl:text 元素在其内容之外以避免换行出现在结束的处理指令中,因为它不能 -- 内容包括两个 xsl:value-of 元素,而一个 xsl:text 元素不能够有任何子元素。结果的处理指令仍然是完全合法的 XML)
与 xsl:comment 元素类似,一个 xsl:processing-instruction 元素不能是一个顶级元素 -- 如果它是一个 xsl:stylesheet 元素的子元素,一个 XSLT 处理器将忽略它。就象上面的例子所显示的那样,它应该是一个可以添加节点到结果树中的元素 (在这个例子中,即xsl:template) 的子元素。
从你的源树中读取和使用处理指令
一个 XSLT 处理器对于在源树中的处理指令的缺省处理是忽略它们。使用 processing-instruction() 函数,你的样式单可以找到处理指令并添加它们到结果树中。例如,这个模板拷贝所有的处理指令到输出而不做任何改变。
<xsl:template match="processing-instruction()">
<xsl:copy/>
</xsl:template>
XSLT 也使你可以通过必须存在于每个处理指令中的目标的值选择处理指令。与 XSLT 使用 xsl:value-of 元素取出处理器指令内容的能力一起,你可以通过使用指定的处理指令目标利用这个能力转换处理指令到它们自己的元素中。
例如,下列的 XML 文档摘录中有两个处理指令和不同的处理指令目标:xml-stylesheet 和 smellPlugIn。
<?xml-stylesheet href="headlines.css" type="text/css"?>
<verse>And hazard in the Glorious Enterprise</verse>
<?smellPlugIn scent="newCar" duration="12secs"?>
除了转换上面的 verse 元素到一个 p 元素以外,下面的模板规则将转换 xml-stylesheet 处理指令到一个 stylesheet 元素,转换 smellPlugIn 处理指令到一个 smellPlugIn 元素。
<xsl:template match="processing-instruction('xml-stylesheet')">
<stylesheet><xsl:value-of select="."/></stylesheet>
</xsl:template>
<xsl:template match="processing-instruction('smellPlugIn')">
<smellData><xsl:value-of select="."/></smellData>
</xsl:template>
<xsl:template match="verse">
<p><xsl:apply-templates/></p>
</xsl:template>
上面的模板应用例子的输入添加下列内容到结果树中:
<stylesheet>href="headlines.css" type="text/css"</stylesheet>
<p>And hazard in the Glorious Enterprise</p>
<smellData>scent="newCar" duration="12secs"</smellData>
使用我们在这里已经看到的专用的 XSLT 元素和函数,你可以充份利用注释和处理指令可以添加到你的输入和输出文档中的全部灵活性。毕竟有的时候 XML 文档并不仅仅是元素和属性。
相关阅读 更多 +