应用模板时更改顺序?

时间:2017-02-24 16:39:40

标签: xml xslt

例如,我有以下xml:

<items>
  <item value="1">
  <item value="2">
  <item value="3" start="true">
  <item value="4">
  <item value="5">
</items>

和xsl一样:

<ul>
  <xsl:apply-templates select="item"/>
</ul>

<xsl:template match="item">
  <li><xsl:value-of select="@value"/></li>
</xsl:template>

按文档顺序输出项目。但是我希望它从指定的位置开始,所以输出的顺序是3,4,5,1,2。这可以不用改变文档中的顺序吗?

谢谢!

编辑:

以下作品:

<xsl:apply-templates select="item">
  <xsl:sort data-type="number" select="position()-count(../item[@start]/preceding-sibling::item)+count(../item)*boolean(position()&lt;=count(../item[@start]/preceding-sibling::item)"/>
</xsl:apply-templates>

1 个答案:

答案 0 :(得分:2)

你可以改变:

<ul>
  <xsl:apply-templates select="item"/>
</ul>

为:

<ul>
    <xsl:apply-templates select="item[@start='true']"/>
    <xsl:apply-templates select="item[@start='true']/following-sibling::item"/>
    <xsl:apply-templates select="item[@start='true']/preceding-sibling::item"/>
</ul>

这将在给定示例中产生预期结果。这是否是你想要适用的规则我不清楚。

加了:

  

如果开始标记是可选的,那该怎么办?所以,如果没有它   按文件顺序输出,但如果有,则从那里开始?

好吧,你可以像这样拆分决策树:

<ul>
    <xsl:choose>
        <xsl:when test="item[@start='true']">
            <xsl:apply-templates select="item[@start='true']"/>
            <xsl:apply-templates select="item[@start='true']/following-sibling::item"/>
            <xsl:apply-templates select="item[@start='true']/preceding-sibling::item"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="item"/>
        </xsl:otherwise>
    </xsl:choose>
</ul>

或者,如果您愿意,可以将其缩短为:

<ul>
    <xsl:apply-templates select="item[@start='true']"/>
    <xsl:apply-templates select="item[@start='true']/following-sibling::item"/>
    <xsl:apply-templates select="item[@start='true']/preceding-sibling::item"/>
    <xsl:apply-templates select="item[not(../item[@start='true'])]"/>
</ul>

这两个指令都避免了可能很昂贵的xsl:sort指令 - 更不用说这种类型需要的疯狂复杂的计算。