如何在xsl:perform-sort中声明变量

时间:2016-07-08 06:57:35

标签: xslt xslt-2.0

我有一个像这样的复杂排序:

        <xsl:perform-sort select="$nodes">
        <xsl:sort select="if (p:isPreform(.) and not(p:getPreformPart(., $nodes))) then 1 else 0"/>
        <xsl:sort select="p:getTargetPart(., $nodes)/../@pos"/>
        <xsl:sort select="if (sort:isGroupElement(p:getTargetPart(., $nodes), $subsectionId)) then
                                sort:getGroupId(p:getTargetPart(., $nodes), $subsectionId)
                          else
                                p:getTargetPart(., $nodes)/@name"/>
        <xsl:sort select="if (sort:isGroupElement(p:getTargetPart(., $nodes), $subsectionId)) then 0 else 1"/>
        <xsl:sort select="replace(p:getTargetPart(., $nodes)/@number, '[А-Я]+$','')"/>
        <xsl:sort select="if (p:isPreform(.)) then 1 else 0"/>
        <xsl:sort select="@number"/>
    </xsl:perform-sort>

你可以在里面看到重复的结构。我怎么能重构这个?如果是这样的话,规范不允许在里面声明变量 - 相同的片段可能看起来像:

        <xsl:perform-sort select="$nodes">
        <xsl:variable name="isPreform" select="p:isPreform(.)" as="xs:boolean"/>
        <xsl:variable name="target" select="p:getTargetPart(., $nodes)" as="element()"/>
        <xsl:variable name="isGrouped" select="sort:isGroupElement($target, $subsectionId)" as="xs:boolean"/>

        <xsl:sort select="if ($isPreform and not(p:getPreformPart(., $nodes))) then 1 else 0"/>
        <xsl:sort select="$target/../@pos"/>
        <xsl:sort select="if ($isGrouped) then sort:getGroupId($target, $subsectionId) else $target/@name"/>
        <xsl:sort select="if ($isGrouped) then 0 else 1"/>
        <xsl:sort select="replace($target/@number, '[А-Я]+$','')"/>
        <xsl:sort select="if ($isPreform) then 1 else 0"/>
        <xsl:sort select="@number"/>
    </xsl:perform-sort>

也许我想念一些东西?我可以通过另一种方式对此进行排序吗?

提前谢谢!安德烈。

1 个答案:

答案 0 :(得分:1)

也许我说的很明显,但是通过在<xsl:perform-sort>内添加变量来实现以下内容而不是寻求妥协更具可读性。 XSLT 2.0的创建者不允许这样做的一个原因可能是阻止复杂性 - 因此没有允许序列构造函数作为<xsl:perform-sort>的主体 - 就像它不允许在体内一样。 <xsl:apply-templates>

我会使用(并鼓励大家使用)这样的东西

   <xsl:perform-sort select="$nodes">
        <xsl:sort select="f:key1(., $nodes)"/>
        <xsl:sort select="f:key2(., $nodes)"/>
        <xsl:sort select="f:key3(., $nodes, $subsectionId)"/>
        <xsl:sort select="f:key4(., $nodes, $subsectionId)""/>
        <xsl:sort select="f:key5(., $nodes))"/>
        <xsl:sort select="f:key6(.)"/>
        <xsl:sort select="@number"/>
    </xsl:perform-sort>

这里我将为函数f:keyN()提供有意义的名称,这样就可以理解排序规则是什么。

任何重复的表达式都是由单独的函数实现的候选者,并在必要时由其他函数调用。因此可以并且将避免冗余 - 这是一个称为抽象的主要编程原则。