XSLT Сортировать по алфавиту и численно проблема
У меня есть группа строк ie g: lines = '9,1,306, LUCY, G, 38, 12'
Мне нужно, чтобы выход был в XSLT 1.0:
1,9,12,38,306,Г,ЛЮСИ!--2-->
Это мой текущий код:
<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, Джи, Люси, потому что второй сорт не забирают.
кто-нибудь может мне помочь?
4 ответов
чтобы достичь этого, используя только один оператор 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:вроде сортировка, является ли строка числом или нет. The не() возвращает false, если строка является числом, и true, если это не так. false сортируется перед true, и поэтому числа выходят первыми. Если вы опустите этот вид, буквы появятся первыми.
следующий язык 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 для тестирования, если значение не является числом.
другим (более чистым, я думаю) решением было бы выбрать/отсортировать первые числа, а затем другие.
Я считаю, что это выполняет то, что вы хотите.
Я сначала разделил оценку/сортировку чисел, а затем текстовые значения узлов.
<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>