首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 XSLT 转换属性

使用 XSLT 转换属性

类和方法是面向对象程序员的工具,用于把大型应用程序组织成较小的、更加可管理的单元。XSLT 程序员为了同样的目的使用模板。当模式和当前节点匹配时,处理器就把控制交给模板。
这种模式匹配机制特别适用于处理树状结构(如 XML 文档)。从而形成了声明性的编程风格,因为避免了编写所有的树遍历和树处理例程。相反,由处理器遍历输入文档并自动为节点选择最合适的模板。
当不知道元素在输入文档中的出现顺序或者是否重复时,模式匹配特别方便。同样,处理器负责重复调用模板解决重复问题。
测试属性多数模板都是为匹配元素而编写的。当样式表处理属性时,规则通常附加在匹配元素的模板中,如清单 1 所示(本文中的所有例子都摘自 DocBook-to-HTML样式表):
清单 1. 处理附加在元素中的属性
1
2
3
<xsl:template match="ulink">
   <a href="{@url}"><xsl:apply-templates/></a>
</xsl:template>




这个模板转换         ulink 元素和         url 属性,但只与         ulink 元素匹配。      
如果属性是必需的——换句话说,它一定会出现,则对元素匹配是合理的。但是如果属性是可选的,您就得在输出中生成某些内容        之前测试该属性是否存在。有些情况下,希望通过模式中的条件进行测试,比如清单 2:      
清单 2. 在模板匹配中测试属性
1
2
3
<xsl:template match="emphasis[@type='bold']">
   <b><xsl:apply-templates/></b>
</xsl:template>




匹配属性测试属性并不总是可行的。看一看 DocBook 中图片         imagedata 的标记。         imagedata 有可选的         width 和         depth 属性可能需要保存到 HTML 中。对所有可能的组合编码太困难了(         imagedata[@width] ,         imagedata[@depth] 和         imagedata[@width         and @depth] ——就是说仅仅为了        两个属性要使用三个模板)。更合理的办法是让处理器遍历属性节点并针对属性节点编写模板,如清单 3 所示:      
清单 3. 匹配属性的模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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. 匹配带条件的属性
1
2
3
<xsl:template match="videodata/@fileref">
   <param name="src" value="{.}"/>
</xsl:template>




此外,还可以在调用者中通过         select="@* | node()" 属性把模板应用于属性和元素内容,如清单 5所示:      
清单 5. 调用模板处理元素和属性
1
2
3
<xsl:template match="para">
   <p><xsl:apply-templates select="@* | node()"/></p>
</xsl:template>




这个技巧是 XSLT 编码中更一般原则的实际例子:为了使样式表更加可维护,把工作分到几个模板中是值得的。
返回列表