xsl中字符串的初始数字部分或整数部分

时间:2010-11-15 15:44:37

标签: xml string xslt xpath numbers

通过使用xsl模板,任何人都可以告诉我获取字符串字段的第一个数字部分的方法

例如:

'12'        -> should result in -> 12
'5 ASDF'    -> should result in -> 5
'34SDF56'   -> should result in -> 34

3 个答案:

答案 0 :(得分:4)

这是一个单线XPath解决方案 :: :)

<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>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
 <x>12</x>
 <x>5 ASDF</x>
 <x>34SDF56</x>
</t>

生成所需的正确结果

12
5
34

答案 1 :(得分:1)

你能放手一搏吗?假设您知道数字的最大长度,应该工作!

所以在这里你可以找到长达6位数的数字!希望它有所帮助

      <xsl:variable name="YourString" select="YourStringPath"/>
      <xsl:choose>
            <xsl:when test="substring($YourString,1,6) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,6)"/>
            </xsl:when>
            <xsl:when test="substring($YourString,1,5) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,5)"/>
            </xsl:when>
            <xsl:when test="substring($YourString,1,4) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,4)"/>
            </xsl:when>
            <xsl:when test="substring($YourString,1,3) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,3)"/>
            </xsl:when>
            <xsl:when test="substring($YourString,1,2) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,2)"/>
            </xsl:when>
            <xsl:when test="substring($YourString,1,1) &gt; 0">
                  <xsl:value-of select="substring($YourString,1,1)"/>
            </xsl:when>
            <xsl:otherwise>default number here?</xsl:otherwise>         
      </xsl:choose>

答案 2 :(得分: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>

(感谢@Alejandro的关键思路,使用substring()获取第一个非数字,然后将其传递给substring-before()。)这里是在身份变换的上下文中:

<?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>

在以下输入上运行时:

<?xml version="1.0" encoding="UTF-8"?>
<values>
   <value num="12"/>
   <value num="5 ASDF"/>
   <value num="34SDF56"/>
</values>

它产生请求的输出:

<?xml version="1.0" encoding="utf-8"?>
<values>
   <value num="12"/>
   <value num="5"/>
   <value num="34"/>
</values>

另一种执行@num模板的方法如下,可以说更优雅但更难以阅读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>

注意:

  • 上面两个@num模板中的第一个在第二个上采用优先级,因为第一个更具体,具有谓词。因此,第一个模板用于处理匹配的@ num,第二个模板处理所有其他@ num的。
  • 第一个模板匹配@ num的值,该值是所有数字,仅复制属性。如果我们没有发出此异常,则第二个模板将为此类@ num的输出空字符串值。