Начальная часть числа или целая часть строки в xsl - PullRequest
1 голос
/ 15 ноября 2010

Используя шаблон xsl, любой может подсказать мне, как получить первую числовую часть строкового поля

Например:

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

Ответы [ 3 ]

4 голосов
/ 15 ноября 2010

Вот однострочное решение 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 голос
/ 15 ноября 2010

Вы могли бы попробовать? должно работать, если вы знаете максимальную длину чисел!

так что здесь вы можете найти номер длиной до 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>
0 голосов
/ 15 ноября 2010

Следующий шаблон будет выдавать все числовые цифры строки вплоть до первой нечисловой (без необходимости знать, сколько цифр может быть в числе):

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