如何更改每个xsl的顺序?

Gab*_*iel 4 xslt

只有在满足某些条件时,我才需要更改执行for-each的顺序.

这是我的XML的样子:

<OptionList>
    <Option name="My First Option" />
    <Option name="My Second Option" />
</OptionList>
Run Code Online (Sandbox Code Playgroud)

但是,在某些情况下,我的XML可以是这样的:

<OptionList>
    <Option />
    <Option name="My Second Option" />
</OptionList>
Run Code Online (Sandbox Code Playgroud)

在我的XSL中,我正在为这样做:

<xsl:for-each select="//OptionList/Option">
    {...}
</xsl:for-each>
Run Code Online (Sandbox Code Playgroud)

我知道我可以在for-each中使用此行来更改Option节点的顺序:

<xsl:sort select="position()" data-type="number" order="descending" />
Run Code Online (Sandbox Code Playgroud)

问题是我希望我的订单仅在我的第一个Option节点为空且没有name属性时才下降.否则,我想保持默认的升序.

关于如何实现这一点的任何意见?到目前为止,我尝试的所有内容都以"变量超出范围"或无效使用xpath函数结束.

Dir*_*mar 5

您可以使用hack根据条件更改排序顺序:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <result>
    <xsl:for-each select="//OptionList/Option">
      <xsl:sort data-type="number" order="ascending"
        select="position()*(-2*number(not(//OptionList/Option[1]/@name))+1)"/>

      <option>
        <xsl:value-of select="@name"/>
      </option>
    </xsl:for-each>
    </result>

  </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

黑客是number((true())返回1并number(false())返回0.因此,表达式

-2 * number(not(//OptionList/Option[1]/@name)) + 1
Run Code Online (Sandbox Code Playgroud)

评估1第一个option元素是否具有name属性,-1否则.这用作反转排序顺序的因素.