XSLT 按字母顺序排序 &数值问题

发布于 2024-08-29 03:06:17 字数 603 浏览 7 评论 0原文

我有一组字符串,即 g:lines = '9,1,306,LUCY,G,38,12'

我需要输出为 XSLT 1.0:

1,9,12,38,306,G,LUCY

这是我当前的代码:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']">
  <xsl:sort select="g:line"/>
  <xsl:sort select="number(g:line)" data-type="number"/>
  <xsl:value-of select="normalize-space(g:line)" /><xsl:text/>
  <xsl:if test="position()!=last()"><xsl:text>,&#160;</xsl:text></xsl:if>
</xsl:for-each>

我可以让它只显示“1,12,306,38,9,G,LUCY”,因为第二个排序没有被选择。

有人能帮我吗?

I have a group of strings ie g:lines = '9,1,306,LUCY,G,38,12'

I need the output to be in XSLT 1.0:

1,9,12,38,306,G,LUCY

This is my current code:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']">
  <xsl:sort select="g:line"/>
  <xsl:sort select="number(g:line)" data-type="number"/>
  <xsl:value-of select="normalize-space(g:line)" /><xsl:text/>
  <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>
</xsl:for-each>

I can get it to only display '1, 12, 306, 38, 9, G, LUCY' because the 2nd sort isn't being picked up.

Anyone able help me out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白昼 2024-09-05 03:06:17

要仅使用一个 xsl:foreach 语句来实现此目的,请尝试以下操作:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']"> 
  <xsl:sort select="not(number(g:line))"/> 
  <xsl:sort select="number(g:line)" data-type="number"/> 
  <xsl:sort select="g:line"/> 
  <xsl:value-of select="normalize-space(g:line)" /><xsl:text/> 
  <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if> 
</xsl:for-each> 

第一个 xsl:sort 根据行是否为数字进行排序。如果该行是数字,则 not() 返回 false,否则返回 true。 false 排在 true 之前,因此数字先出现。如果省略这种排序,字母将首先出现。

下一个 xsl:sort 按数字排序,因此将正确对数字进行排序,但不会影响字母(当应用 number() 时,所有字母都返回 NaN)。

最终的xsl:sort将按字母顺序对字母进行排序。

To achieve this using just one xsl:foreach statement, try the following:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']"> 
  <xsl:sort select="not(number(g:line))"/> 
  <xsl:sort select="number(g:line)" data-type="number"/> 
  <xsl:sort select="g:line"/> 
  <xsl:value-of select="normalize-space(g:line)" /><xsl:text/> 
  <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if> 
</xsl:for-each> 

The first xsl:sort sorts on whether the line is a number or not. The not() returns false if the line is a number, and true if it isn't. false is sorted before true, and so the numbers come out first. If you omit this sort, the letters will appear first.

The next xsl:sort sorts numerically, and so will sort the numbers correctly, but not affect the letters (which all return NaN when number() is applied).

The final xsl:sort will sort the letters alphabetically.

指尖微凉心微凉 2024-09-05 03:06:17
<xsl:template match="/">
  <xsl:for-each select="(9,1,306,'LUCY','G',89)" >
    <xsl:sort select="if (number()) then () else ."/>
    <xsl:sort select="number(.)" data-type="number" />
    <xsl:value-of select="."/>
    <xsl:value-of select="', '" />
  </xsl:for-each>
</xsl:template>

给我

1, 9, 89, 306, G, LUCY,

我想这就是你需要的,对吧?

<xsl:template match="/">
  <xsl:for-each select="(9,1,306,'LUCY','G',89)" >
    <xsl:sort select="if (number()) then () else ."/>
    <xsl:sort select="number(.)" data-type="number" />
    <xsl:value-of select="."/>
    <xsl:value-of select="', '" />
  </xsl:for-each>
</xsl:template>

gives me

1, 9, 89, 306, G, LUCY,

I guess that is what you need, right?

在 XSLT 1.0 中,我认为您需要这样的东西:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']">  
    <xsl:sort select="g:line[number(g:line) != number(g:line)]"/>  
    <xsl:sort select="g:line[number(g:line) = number(g:line)]" data-type="number"/>
    <xsl:value-of select="normalize-space(g:line)" /><xsl:text/>  
    <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>  
</xsl:for-each>

number($foo) != number($foo) 是用于测试值是否不是数字的 XSLT 1.0 习惯用法。

另一个(我猜更干净)的解决方案是选择/排序第一个数字,然后是其他数字。

In XSLT 1.0 I think you need something like this:

<xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus']">  
    <xsl:sort select="g:line[number(g:line) != number(g:line)]"/>  
    <xsl:sort select="g:line[number(g:line) = number(g:line)]" data-type="number"/>
    <xsl:value-of select="normalize-space(g:line)" /><xsl:text/>  
    <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>  
</xsl:for-each>

number($foo) != number($foo) is XSLT 1.0 idiom for testing if a value is not a number.

Another (more clean I guess) solution would be to select/sort first numbers, then others.

怀里藏娇 2024-09-05 03:06:17

我相信这可以实现你想要的。

我首先拆分出数字的评估/排序,然后拆分出文本节点值。

    <xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)=number(g:line)]">
        <xsl:sort select="g:line" data-type="number" order="ascending"/>
        <xsl:value-of select="normalize-space(g:line)" />
        <xsl:text/>
        <xsl:if test="position()!=last() or $all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)!=number(g:line)]">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>

    <xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)!=number(g:line)]">
        <xsl:sort select="g:line[number(g:line) != number(g:line)]"/>
        <xsl:value-of select="normalize-space(g:line)" />
        <xsl:text/>
        <xsl:if test="position()!=last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>

I believe this accomplishes what you want.

I split out the evaluation/sort of numbers first and then text node values.

    <xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)=number(g:line)]">
        <xsl:sort select="g:line" data-type="number" order="ascending"/>
        <xsl:value-of select="normalize-space(g:line)" />
        <xsl:text/>
        <xsl:if test="position()!=last() or $all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)!=number(g:line)]">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>

    <xsl:for-each select="$all_alerts[g:problem!='normal_service'][g:service='bus'][number(g:line)!=number(g:line)]">
        <xsl:sort select="g:line[number(g:line) != number(g:line)]"/>
        <xsl:value-of select="normalize-space(g:line)" />
        <xsl:text/>
        <xsl:if test="position()!=last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文