给定此源文档:
<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.
调试。您能否建议如何转储中间结果,这些结果将指示template
as
属性的存在与不存在之间的差异?
看 http://www.w3.org/TR/xslt20/#value-of 上面写着
新文本节点的字符串值可以通过使用以下 select 属性,或通过序列构造函数(参见 5.7 序列 构造函数(,它构成 xsl:value-of 元素的内容。 它们是互斥的,其中之一必须存在。方式 构造值在 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 ', .)"/>
则序列构造函数是基元字符串值序列。