我有一个像这样的复杂排序:
<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>
也许我想念一些东西?我可以通过另一种方式对此进行排序吗?
提前谢谢!安德烈。
答案 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()
提供有意义的名称,这样就可以理解排序规则是什么。
任何重复的表达式都是由单独的函数实现的候选者,并在必要时由其他函数调用。因此可以并且将避免冗余 - 这是一个称为抽象的主要编程原则。