开始使用 XSLT,这很有趣,我喜欢校长,虽然需要一点时间来适应。现在......我已经遇到了一个我想知道的问题,也许有人可以启发我。
我有一组优先的盒子。优先级较低的框首先出现。这很好用。但是,我想将我的盒子排成一行,并将第 1 行和第 3 行标记为奇数,将第 2 行标记为偶数(我预计在实际项目中会有更多行。)
因此,我认为我应该能够使用 fn:position() 函数。不幸的是,返回的位置是原始节点之一,而不是结果排序节点。有没有办法解决这个问题?
有一个示例 XSLT 暴露了这个问题:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="body">
<xsl:apply-templates>
<xsl:sort select="@priority" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="body/box">
<div class="box">
Box[<xsl:value-of select="count(preceding-sibling::box) + 1" />,<xsl:value-of select="position()"/>] = (<xsl:value-of select="@priority"/>)
<xsl:copy-of select="title"/></div>
</xsl:template>
</xsl:stylesheet>
还有一个输入的例子。应该首先出现两个,然后是三个,最后是一个。
<?xml version="1.0"?>
<body>
<box priority="103">
<title>This is box ONE</title>
</box>
<box priority="1">
<title>This is box TWO</title>
</box>
<box priority="12">
<title>This is box THREE</title>
</box>
</body>
但是我希望 position() 为 1、2 和 3 ......但这是输出:
<div class="box">
Box[2,4] = (1)
<title>This is box TWO</title>
</div>
<div class="box">
Box[3,6] = (12)
<title>This is box THREE</title>
</div>
<div class="box">
Box[1,2] = (103)
<title>This is box ONE</title>
</div>
Box 方括号内的第二个数字是 position()。我预期为 1、2、3。但正如我们所见,我们得到 4、6、2,这是原始文档中节点的位置(我不太确定为什么它是 x2,但当我用xsl:for-each 标签,它是 2、3 和 1。)
我用 xmlpatterns (Qt 4.7) 和 xsltproc (libxml2,这应该使用 1.0 版本,代码与 1.0 兼容) 进行了测试,并且两者都返回相同的数字。
那么......这是 XSLT 的限制,还是这两个 XSLT 实现中的错误?!
2012 年 5 月 27 日更新
已确定 QXmlQuery (xmlpatterns) 在该特定情况下是一个损坏的解析器。position() 必须使用类似的东西来计算,count(preceding-sibling::box) + 1
而不是在运行的 for-each 或模板序列中使用正确的索引。