xsl:template的“as”属性如何影响xsl:apply-templates的结果

时间:2013-09-26 17:49:14

标签: xslt-2.0

鉴于此源文件:

<things>
  <thing><duck>Eider</duck></thing>
  <thing><duck>Mallard</duck></thing>
  <thing><duck>Muscovy</duck></thing>
</things>

我需要以下输出

Fat Eider, Fat Mallard, Fat Muscovy

我确实可以使用这个XSL转换:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" >
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:value-of separator=", ">
      <xsl:apply-templates select="//duck"/>
    </xsl:value-of>
  </xsl:template>
  <xsl:template match="duck" as="xs:string">
    <xsl:value-of select="concat('Fat ', .)"/>
  </xsl:template>
</xsl:stylesheet>

但是,我有三个问题:

问题1。(具体)

如果我从duck模板中删除as="xs:string",我会得到以下输出:

    Fat EiderFat MallardFat Muscovy 

为什么呢?我的理解是,在XSLT 2.0中,xsl:apply-templates的结果始终是一个序列,xsl:value-of在序列中的项之间插入separator。那么,当模板没有as属性时,为什么序列似乎“崩溃”?奖励积分指向迈克凯的优秀“XSLT 2.0和XPath 2.0,第4版”书的适当页面。

问题2。(含糊不清!)

作为XSLT的新手用户,在我看来可能有很多方法可以解决这个问题。你能提出一个采用不同方法的好解决方案吗?你如何选择方法?

问题3。

调试。您能否推荐如何转出中间结果,以表明as属性的存在与否的区别?

1 个答案:

答案 0 :(得分:3)

请参阅http://www.w3.org/TR/xslt20/#value-of说明

  

可以通过使用来定义新文本节点的字符串值   select属性,或序列构造函数(参见5.7 Sequence   构造函数)构成xsl:value-of元素的内容。   这些是相互排斥的,其中一个必须存在。方式   其中构造的值在5.7.2 Constructing中指定   简单内容。

所以我们需要看一下http://www.w3.org/TR/xslt20/#constructing-simple-content,然后说&#34; 2。序列中的相邻文本节点合并为单个文本节点。&#34;。这就是没有as="xs:string"的情况,xsl:value-of内的序列构造函数创建了合并为单个文本节点的相邻文本节点。如果您有as="xs:string"<xsl:sequence select="concat('Fat ', .)"/>,则序列构造函数是一系列原始字符串值。