[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XPath MOD 10 calculation

Subject: Re: XPath MOD 10 calculation
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Thu, 24 May 2007 14:47:12 +0200
Re:  XPath MOD 10 calculation
Jesper,

I don't know if these UPC codes can have variable length. But if they can, your algorithm should be reversed. That is, the rightmost digit is the first digit (the odd digit).

Note that there are four important differences between the UPC mod10 algorithm and the traditional Luhn mod10 algorithm:

1. Odd and Even digits are reversed (Luhn doubles each even digit, UPC triples each odd digit)
2. UPC does not add individual digits from the result of step 1, instead, it merely add the result
3. UPC triples, where Luhn doubles digits
4. UPC adds a checksum at the rightmost position, which should not be taken into the calculation itself


I believe from looking at your code that 2, 3 and 4 are considered in your code, but 1 is not (esp. not calculated from the right).

Here's a Luhn's algorithm in a single XPath (tested):

sum(for $j in
(for $i in reverse(string-to-codepoints(.))[position() mod 2 = 0] return ($i - 48) * 2,
for $i in reverse(string-to-codepoints(.))[position() mod 2 = 1] return ($i - 48))
return ($j mod 10, $j idiv 10))



Here's UPC's algorithm, based on the above, in a single XPath (*not* tested by lack of testing material and specs):


sum(
for $i in reverse(string-to-codepoints(substring(., 1, string-length(.) - 1))[position() mod 2 = 1] return ($i - 48) * 3,
for $i in reverse(string-to-codepoints(substring(., 1, string-length(.) - 1)))[position() mod 2 = 10 return ($i - 48))
= number(substring(., string-length(.) - 1, 1))



You could consider to put the repeated logic inside a variable, in which case the expression becomes easier:


<xsl:variable name="x" select="for $i in reverse(string-to-codepoints(substring(., 1, string-length(.) - 1)) return $i - 48" />

the XPath then becomes:

   sum(
       for $i in $x[position() mod 2 = 1] return $i * 3,
       for $i in $x[position() mod 2 = 0] return $i,
       = number(substring(., string-length(.) - 1, 1))


Cheers, -- Abel Braaksma


Jesper Tverskov wrote:
On 5/24/07, Abel Braaksma <abel.online@xxxxxxxxx> wrote:

Is yours the same as describe here
http://en.wikipedia.org/wiki/Luhn_algorithm ? Because it seems to me
that your code does not equal that description.

I have until now used this one: http://www.idautomation.com/upceanfaq.html

I have a feeling that I must look into exactly what bar codes are used
these days, before I continue.

Jesper

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.