xslt 转换乱码
类和方法是面向对象的程序员用来将大型应用程序组织为更小,更易于管理的单元的工具。 XSLT程序员将模板用于相同的目的。 当处理器的模式与当前节点匹配时,处理器将控制权交给模板。
这种模式匹配机制特别适合处理树(例如XML文档)。 它导致了声明式的编程风格,因为它省去了编写所有树遍历和树操作例程的麻烦。 取而代之的是,处理器浏览输入的文档并自动为节点选择最合适的模板。
当您不知道元素在输入文档中的显示顺序或是否重复时,模式匹配特别方便。 同样,处理器通过重复调用模板来处理重复。
测试属性
大多数模板都是为匹配元素而编写的。 当样式表处理属性时,规则通常会附加到与元素匹配的模板上,如清单1所示(本文中的所有示例均摘自DocBook-to-HTML样式表):
清单1.处理附加到元素的属性
<xsl:template match="ulink">
<a href="{@url}"><xsl:apply-templates/></a>
</xsl:template>
该模板可转换ulink
元素和url
属性,但仅与ulink
元素匹配。
如果需要该属性,则与该元素进行匹配是有意义的-换句话说,如果必须存在该属性。 但是,如果该属性是可选的,则需要在输出中生成任何内容之前测试它是否存在。 在某些情况下,您需要测试模式中的条件,如清单2所示:
清单2.测试模板匹配中的属性
<xsl:template match="emphasis[@type='bold']">
<b><xsl:apply-templates/></b>
</xsl:template>
匹配属性
测试属性并不总是可行的。 看一下图像的标记imagedata
中的imagedata
。 imagedata
具有可选的width
和depth
属性,您可能希望将其保存在HTML中。 对于所有可能的组合( imagedata[@width]
, imagedata[@depth]
和imagedata[@width and @depth]
,这是只有两个属性的三个模板),很难进行编码。 让处理器遍历属性节点并针对它们编写模板是更明智的,如清单3所示:
清单3.匹配属性的模板
<xsl:template match="imagedata">
<img><xsl:apply-templates select="@*"/></img>
</xsl:template>
<xsl:template match="@width">
<xsl:attribute name="width">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@depth">
<xsl:attribute name="height">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@fileref">
<xsl:attribute name="href">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
请注意,默认情况下,处理器不会遍历属性节点。 您必须使用select="@*"
属性明确要求。
模板匹配元素和模板匹配属性之间的两个重要区别是:
- 属性是叶子。
xsl:apply-templates
指令无处可寻,因为属性没有子代供处理器使用。 请改用xsl:value-of
。 - 输入中的大多数属性也是输出中的属性。 使用
xsl:attribute
在输出树中插入一个属性。 但是要小心xsl:attribute
必须出现在任何其他子级之前。 换句话说,xsl:apply-templates
指令必须位于调用方中的任何文本或子元素之前。
模板无限制
属性上的匹配为您提供XSLT的完整表达能力。 模板不限于将一个属性转换为另一个属性。 您可以向模式添加条件或将属性转换为元素。 清单4个定义了一个特殊规则中的模板匹配fileref
作为一个属性videodata
。 它创建一个元素而不是一个属性。
清单4.匹配具有条件的属性
<xsl:template match="videodata/@fileref">
<param name="src" value="{.}"/>
</xsl:template>
另外,在调用方中,您可以将模板应用于属性以及带有select="@* | node()"
属性的元素内容,如清单5所示:
清单5.调用模板处理元素和属性
<xsl:template match="para">
<p><xsl:apply-templates select="@* | node()"/></p>
</xsl:template>
本技巧是XSLT编码中更通用的规则的实际示例:为了使样式表更具可维护性,值得在几个模板之间划分工作。
翻译自: https://www.ibm.com/developerworks/xml/library/x-tipattr/index.html
xslt 转换乱码