XSLT を使い始めるのは楽しいです。慣れるまで少し時間がかかりますが、私はプリンシパルが好きです。今...私はすでに疑問に思っている問題に遭遇しました。おそらく誰かがそれについて教えてくれるかもしれません。
プライオリティのあるボックスのセットがあります。優先度の低いボックスが最初に表示されます。これはうまくいきます。ただし、ボックスを行に配置し、行 1 と 3 を奇数としてマークし、行 2 を偶数としてマークしたいと思います (実際のプロジェクトでは、さらに多くの行があると予想されます)。
したがって、 fn:position() 関数を使用できるはずだと思いました。残念ながら、返される位置は元のノードの 1 つであり、結果の並べ替えられたノードではありません。その問題を解決する方法はありますか?
問題を明らかにするサンプル 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>
入力例もあります。TWO が最初に表示され、次に THREE、最後に ONE が表示されます。
<?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>
ボックス角括弧内の 2 番目の数字は position() です。私は 1、2、3 と予想されていました。 xsl:for-each タグではなく、2、3、および 1 でした。)
xmlpatterns (Qt 4.7) と xsltproc (libxml2、これはバージョン 1.0 を使用する必要があり、コードは 1.0 と互換性があります) でテストしたところ、どちらも同じ数値を返しました。
それで...それは XSLT の制限ですか、それともこれら 2 つの XSLT 実装のバグですか?!
2012 年 5 月 27 日更新
その特定のケースでは、QXmlQuery (xmlpatterns) が破損したパーサーであることが判明しました。count(preceding-sibling::box) + 1
position()は、実行中の for-each またはテンプレート シーケンスの正しいインデックスではなく、 に似たものを使用して計算する必要があります。