Ниже приведен вывод вышеприведенного решения XSLT v1, однако это специально для старшего числа, в отличие от встроенного в середине строки. Это также учитывает разбор с плавающей запятой или целочисленный. (Лично я нахожу это полезным для разделения единиц от значений, таких как «80 мг» или «128,4 мм2», где единицей является «мм2», а значение «128,4», а НЕ «128,42».
<xsl:template name="parseNumber">
<xsl:param name="data"/>
<xsl:param name="is-float" select="false()"/><!-- has this already been determined to be a non-integer -->
<xsl:if test="string-length($data) > 0">
<xsl:if test="(substring($data,1,1)>-1) or ((substring($data,1,1) = '.') and (not($is-float)) )">
<xsl:value-of select="substring($data,1,1)"/>
<xsl:call-template name="parseNumber">
<xsl:with-param name="data" select="substring($data,2)"/>
<xsl:with-param name="is-float" select="(substring($data,1,1) = '.') or ($is-float)"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
Ниже приведены примеры юнит-тестов со сравнительными результатами:
Test: [123] ?=? numer(): [123] ?=? for-each-char: [123] ?=? parseNumber: [123]
Test: [1.23] ?=? numer(): [1.23] ?=? for-each-char: [1.23] ?=? parseNumber: [1.23]
Test: [1.1.1.1] ?=? numer(): [NaN] ?=? for-each-char: [1.1.1.1] ?=? parseNumber: [1.1]
Test: [123 abc] ?=? numer(): [NaN] ?=? for-each-char: [123] ?=? parseNumber: [123]
Test: [123 abc2] ?=? numer(): [NaN] ?=? for-each-char: [1232] ?=? parseNumber: [123]
Test: [123.456 abc7] ?=? numer(): [NaN] ?=? for-each-char: [123.4567] ?=? parseNumber: [123.456]
Test: [abc def ] ?=? numer(): [NaN] ?=? for-each-char: [] ?=? parseNumber: []
Test: [abc 123] ?=? numer(): [NaN] ?=? for-each-char: [123] ?=? parseNumber: []