XSLT сортирует по алфавиту и численно проблему
-
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>, </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>, </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>, </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>, </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>