我在包含树的一部分的select属性中应用带变量的模板。从那里我调用另一个应用模板与follow-sibling :: construction,但它适用于所有树。例如:
<a>
<b id="1" ol="1" />
<b id="2" ol="0" />
<b id="3" ol="0" />
<b id="4" ol="1" />
<b id="5" ol="0" />
<b id="6" ol="0" />
<b id="7" ol="1" />
<b id="8" ol="0" />
<b id="9" ol="0" />
<b id="10" ol="1" />
<b id="11" ol="0" />
<b id="12" ol="0" />
<b id="13" ol="1" />
<b id="14" ol="0" />
<b id="15" ol="0" />
<b id="16" ol="1" />
</a>
...
<xsl:variable name="part" select="b[@ol = 1] />
<xsl:apply-templates mode="top" select="$part[position() mod 3 = 1]" />
...
<xsl:template mode="top" match="*">
<tr>
<xsl:apply-template mode="inner" select=".|following-sibling::b[not(position() > 2)]" />
</tr>
<xsl:template>
<xsl:template mode="inner" match="*">
<p><xsl:value-of select="@id" /></p>
<xsl:template>
我期待的是
<tr><p>1</p><p>4</p><p>7</p></tr>
<tr><p>10</p><p>13</p><p>16</p></tr>
我得到了什么
<tr><p>1</p><p>2</p><p>3</p></tr>
<tr><p>10</p><p>11</p><p>12</p></tr>
那么为什么模板“top”在应用follow-sibling时更改上下文而不是$part
?以及如何获得预期的变体?
答案 0 :(得分:0)
XPath选择输入树中的节点,它永远不会更改该输入树。因此,选择一些节点不会以任何方式改变树中的结构和关系,兄弟姐妹或孩子或祖先保持不变。如果要操作树,请使用XSLT或XQuery。由于您已经使用XSLT,使用XSLT 1.0,您需要编写模板以使用新结构创建结果树片段,然后在应用类似exsl:node-set
的扩展函数后,您可以处理中间树。使用XSLT 2.0,您不需要扩展功能,但需要构建中间树。
要实现您想要的输出,您可以使用
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" method="html"/>
<xsl:template match="a">
<xsl:variable name="part" select="b[@ol = 1]" />
<xsl:apply-templates mode="top" select="$part[position() mod 3 = 1]" />
</xsl:template>
<xsl:template mode="top" match="*">
<tr>
<xsl:apply-templates mode="inner" select=".|following-sibling::b[@ol = 1][not(position() > 2)]" />
</tr>
</xsl:template>
<xsl:template mode="inner" match="*">
<p><xsl:value-of select="@id" /></p>
</xsl:template>
</xsl:stylesheet>
使用XSLT样式表Saxon 6.5.5转换
<a>
<b id="1" ol="1" />
<b id="2" ol="0" />
<b id="3" ol="0" />
<b id="4" ol="1" />
<b id="5" ol="0" />
<b id="6" ol="0" />
<b id="7" ol="1" />
<b id="8" ol="0" />
<b id="9" ol="0" />
<b id="10" ol="1" />
<b id="11" ol="0" />
<b id="12" ol="0" />
<b id="13" ol="1" />
<b id="14" ol="0" />
<b id="15" ol="0" />
<b id="16" ol="1" />
</a>
到
<tr>
<p>1</p>
<p>4</p>
<p>7</p>
</tr>
<tr>
<p>10</p>
<p>13</p>
<p>16</p>
</tr>
答案 1 :(得分:0)
$ part选择@ ol = 1的元素,即元素1,4,7,10,13,16。
$ part [position()mod 3 = 1]选择$ part中$ part中的位置为1,4,7的项目......也就是说,它选择带有id和10的元素。
然后对这些模板应用模板,输出以这两个元素开头的三个元素的组,它们为您提供组(1,2,3)和(10,11,12)。
我认为你的错误可能在于想象position()返回树中元素的位置,而不是你要过滤的列表中元素的位置。