У меня есть группа строк т.е. 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>, </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: sort сортирует, строка - это число или нет. not () возвращает false, если строка является числом, и true, если это не так. ложь сортируется перед истиной, поэтому числа выводятся первыми. Если вы не укажете эту сортировку, буквы появятся первыми.
Следующий xsl: sort выполняет числовую сортировку, поэтому числа отсортировываются правильно, но не влияют на буквы (все они возвращают NaN при применении number ()).
Последний xsl: sort отсортирует буквы в алфавитном порядке.
<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: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>
В 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)! = число ($ foo) - это идиома XSLT 1.0 для проверки того, не является ли значение числом.
Другим (более чистым) решением было бы выбрать / отсортировать сначала числа, затем другие.