2

鉴于此源文件:

<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.(具体)

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

    Fat EiderFat MallardFat Muscovy 

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

问题2。(含糊不清!)

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

问题 3。

调试。您能否推荐如何转储中间结果,这些结果表明as属性的存在和不存在之间的差异template

4

1 回答 1

3

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

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

因此,我们需要查看http://www.w3.org/TR/xslt20/#constructing-simple-content,上面写着“2. 序列中的相邻文本节点合并为一个文本节点。”。这就是在没有 , 的情况下发生的事情as="xs:string",其中​​的序列构造函数xsl:value-of会创建相邻的文本节点,这些节点会合并到一个文本节点中。如果你有as="xs:string"或做过<xsl:sequence select="concat('Fat ', .)"/>序列构造函数是一个原始字符串值序列。

于 2013-09-27T09:23:22.053 回答