By using xsl template, can any one tell me the way to get first number portion of a string field
For examp开发者_开发技巧le:
'12' -> should result in -> 12
'5 ASDF' -> should result in -> 5
'34SDF56' -> should result in -> 34
Here is a one-liner XPath solution: :)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()">
<xsl:variable name="vS" select="concat(.,'Z')"/>
<xsl:value-of select=
"substring-before(translate($vS,translate($vS,'0123456789',''),'Z'),'Z')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<t>
<x>12</x>
<x>5 ASDF</x>
<x>34SDF56</x>
</t>
the wanted, correct results are produced:
12
5
34
you could give this a go? should work supposing that you know the maximum length of numbers!
so here you could find a number upto 6 digits long! hope it helps
<xsl:variable name="YourString" select="YourStringPath"/>
<xsl:choose>
<xsl:when test="substring($YourString,1,6) > 0">
<xsl:value-of select="substring($YourString,1,6)"/>
</xsl:when>
<xsl:when test="substring($YourString,1,5) > 0">
<xsl:value-of select="substring($YourString,1,5)"/>
</xsl:when>
<xsl:when test="substring($YourString,1,4) > 0">
<xsl:value-of select="substring($YourString,1,4)"/>
</xsl:when>
<xsl:when test="substring($YourString,1,3) > 0">
<xsl:value-of select="substring($YourString,1,3)"/>
</xsl:when>
<xsl:when test="substring($YourString,1,2) > 0">
<xsl:value-of select="substring($YourString,1,2)"/>
</xsl:when>
<xsl:when test="substring($YourString,1,1) > 0">
<xsl:value-of select="substring($YourString,1,1)"/>
</xsl:when>
<xsl:otherwise>default number here?</xsl:otherwise>
</xsl:choose>
The following template will emit all numeric digits of a string up to the first non-numeric (without having to know how many digits may be in the number):
<xsl:template match="@num">
<xsl:variable name="nonNumbers" select="translate(., '0123456789', '')"/>
<xsl:attribute name="{name()}">
<xsl:choose>
<xsl:when test="$nonNumbers">
<xsl:value-of select="substring-before(.,
substring($nonNumbers, 1, 1))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
(Thanks to @Alejandro for the key idea, using substring() to get the first non-number, and then passing it to substring-before().) Here it is in the context of an identity transform:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@num">
<xsl:variable name="nonNumbers" select="translate(., '0123456789', '')"/>
<xsl:attribute name="{name()}">
<xsl:choose>
<xsl:when test="$nonNumbers">
<xsl:value-of select="substring-before(., substring($nonNumbers, 1, 1))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
<!-- Identity transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When run on the following input:
<?xml version="1.0" encoding="UTF-8"?>
<values>
<value num="12"/>
<value num="5 ASDF"/>
<value num="34SDF56"/>
</values>
it produces the requested output:
<?xml version="1.0" encoding="utf-8"?>
<values>
<value num="12"/>
<value num="5"/>
<value num="34"/>
</values>
Another way to do the @num
template is the following, arguably more elegant but harder to read IMO:
<xsl:template match="@num[translate(., '0123456789', '') = '']">
<!-- alternatively, match="@num[number(.) > 0]" -->
<xsl:copy />
</xsl:template>
<xsl:template match="@num">
<xsl:attribute name="{name()}">
<xsl:value-of select="substring-before(., substring(
translate(., '0123456789', ''), 1, 1))" />
</xsl:attribute>
</xsl:template>
Notes:
- The first of the two @num templates above takes priority over the second, because the first is more specific, having a predicate. So the first template is used to process @num's that it matches, and the second template processes all other @num's.
- The first template matches @num's whose value is all digits, and merely copies the attribute. If we didn't make this exception, the second template would output empty string values for such @num's.
精彩评论