Sum of Alternative Numbers (XML / XSL)

I need to add alternative digits to the number obtained from the XML file using XSLT, for example, if I get 123456789, I need to calculate the sum of the alternative digits from the very beginning using the XSLT function, can I offer any suggestions on this?

Thank Laxmikanth.S

+3
source share
6 answers

This is very easy to do with XSLT 2.0 (in fact, with only one XPath 2.0 expression):

The following XSLT conversion:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:sequence select=
      "sum(for $n in reverse(string-to-codepoints('123456789'))
                                     [position() mod 2 eq 1]
             return
               $n  - string-to-codepoints('0') 
           )
      "/>
    </xsl:template>
</xsl:stylesheet>

when used in any XML document (not used) gives the correct result:

25

XPath 2.0: string-to-codepoints(), codeepoints-to-string() reverse().


UPDATE: , :

sum(for $n in reverse(string-to-codepoints('123456789'))
                                 [position() mod 2 eq 1]
      return
         xs:integer(codepoints-to-string($n))
    )

, xs : " http://www.w3.org/2001/XMLSchema"

+3

, Luhn (mod 10), IBM developerWorks.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:tns="http://www.example.org/tns" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp" exclude-result-prefixes="dp regexp" xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
  <xsl:template match="/">
    <xsl:call-template name="recLuhn">
      <xsl:with-param name="index" select="1"/>
      <xsl:with-param name="parity" select="string-length(CreditCard) mod 2"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="recLuhn">
    <xsl:param name="index"/>
    <xsl:param name="parity"/>
    <xsl:choose>
      <xsl:when test="$index &lt;= string-length(CreditCard) ">
        <xsl:variable name="sum">
          <xsl:call-template name="recLuhn">
            <xsl:with-param name="index" select="$index + 1"/>
            <xsl:with-param name="parity" select="$parity"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="thisSum">
          <xsl:choose>
            <xsl:when test="$index mod 2 != $parity">
              <xsl:choose>
                <xsl:when test="substring(CreditCard, $index, 1)*2 &gt; 9">
                  <xsl:value-of select="(number(substring(CreditCard, $index, 1)) * 2) - 9"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="number(substring(CreditCard, $index, 1)) * 2"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="number(substring(CreditCard, $index, 1))"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="$thisSum + $sum"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="0"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
+3

XSLT 1.0 FXSL.

, str-reverse, str-foldl :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dvc-foldl-func="dvc-foldl-func"
exclude-result-prefixes="xsl dvc-foldl-func"
>
   <xsl:import href="str-foldl.xsl"/>
   <xsl:import href="strReverse.xsl"/>

   <dvc-foldl-func:delEven/>
   <dvc-foldl-func:add/>

   <xsl:variable name="vFoldlDelEven" 
        select="document('')/*/dvc-foldl-func:delEven[1]"/>
   <xsl:variable name="vFoldlAdd" 
        select="document('')/*/dvc-foldl-func:add[1]"/>

    <xsl:output method="text"/>

    <xsl:template match="/">
       <xsl:variable name="vReversed">
         <xsl:call-template name="strReverse">
           <xsl:with-param name="pStr" select="'123456789'"/>
         </xsl:call-template>
       </xsl:variable>

       <xsl:variable name="vOddDigits">
          <xsl:call-template name="str-foldl">
            <xsl:with-param name="pFunc" select="$vFoldlDelEven"/>
            <xsl:with-param name="pStr" select="$vReversed"/>
            <xsl:with-param name="pA0" select="''"/>
          </xsl:call-template>
      </xsl:variable>

      <xsl:call-template name="str-foldl">
        <xsl:with-param name="pFunc" select="$vFoldlAdd"/>
        <xsl:with-param name="pStr" select="$vOddDigits"/>
        <xsl:with-param name="pA0" select="0"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="dvc-foldl-func:add">
         <xsl:param name="arg1" select="0"/>
         <xsl:param name="arg2" select="0"/>

         <xsl:value-of select="$arg1 + $arg2"/>
    </xsl:template>

    <xsl:template match="dvc-foldl-func:delEven">
         <xsl:param name="arg1"/>
         <xsl:param name="arg2"/>

         <xsl:copy-of select=
           "concat($arg1, 
                   $arg2 * (string-length($arg1) mod 2 = 0)
                  )
           "/>
    </xsl:template>
</xsl:stylesheet>

XML (), :

25

:

  • .
  • 0.
  • ,
+1

EXSL (http://exslt.org), - :

sum(str:tokenize($x,'')[position() mod 2 = 0])

- , .

0

XSLT 2.0, XSLT 1.0. :

<xsl:template match="number">
    <xsl:call-template name="sumdigits">
        <xsl:with-param name="number" select="." />
    </xsl:call-template>
</xsl:template>

<xsl:template name="sumdigits">
    <xsl:param name="number" />
    <xsl:param name="runningtotal">0</xsl:param>
    <xsl:choose>
        <xsl:when test="string-length($number) = 0">
            <xsl:value-of select="$runningtotal" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="lastdigit" select="substring($number, string-length($number), 1)" />
            <xsl:variable name="newrunningtotal" select="number($runningtotal) + number($lastdigit)" />
            <xsl:call-template name="sumdigits">
                <xsl:with-param name="number" select="substring($number, 1, string-length($number) - 2)" />
                <xsl:with-param name="runningtotal" select="$newrunningtotal" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

It works by getting the last digit in the input, adding it to the "current total" and recursively calling the named template with the last two digits of the remote input. When there are no numbers left, the total amount is returned.

This XSLT snippet assumes the input is in XML inside an element named 'number'

   <number>123456789</number>

The result should be 25. As you can see, doing this in XSLT2.0 would be much nicer.

0
source

Yes; do not use XSLT or XML for this, it does not make sense.

-2
source

Source: https://habr.com/ru/post/1715220/


All Articles