XSLT сортирует по алфавиту и численно проблему

StackOverflow https://stackoverflow.com/questions/2670214

  •  28-09-2019
  •  | 
  •  

Вопрос

У меня есть группа строк, т.е. G: Lines = '9,1,306, Люси, г, 38,12'

Мне нужен выход, чтобы быть в XSLT 1.0:

1,9,12,38,306, г, Люси

Это мой текущий код:

<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», потому что 2-й роль не поднимается.

Кто-нибудь в состоянии помочь мне?

Это было полезно?

Решение

Для достижения этого используя только одно заявление 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>,&#160;</xsl:text></xsl:if> 
</xsl:for-each> 

Первый XSL: сортировка Сортирует, является ли строка номер или нет. То нет() Возвращает false, если линия - это номер, и true, если это не так. False отсортирован до правды, и поэтому числа выходят на первое место. Если вы пропустите такого рода, буквы будут появляться в первую очередь.

Следующий XSL: сортировка Сортируется численно, и поэтому будет правильно отсортировать цифры, но не влиять на буквы (которые возвращаются NAN, когда Number () применяется).

Финал XSL: сортировка сортируют буквы в алфавитном порядке.

Другие советы

<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, г, Люси,

Я думаю, что это то, что вам нужно, верно?

В 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>,&#160;</xsl:text></xsl:if>  
</xsl:for-each>

Номер ($ foo)! = number ($ foo) - это XSLT 1.0 IDIOM для тестирования, если значение не является числом.

Другим (более чистым я думаю) решение было бы выбрать / сортировать первые номера, а затем другие.

Я считаю, что это достигает того, что вы хотите.

Я сначала разделил оценку / виды номеров, а затем текстовые значения узла.

    <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>,&#160;</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>,&#160;</xsl:text>
        </xsl:if>
    </xsl:for-each>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top