Creating barcodes in XSL


This document presents an XSL stylesheet to draw UPC/EAN barcodes, created by RenderX, Inc.. Similar techniques may facilitate deployment of XSL-based solutions in production environments where barcode labelling of documents is required.


Barcodes are very simple in physical structure - just rectangular black bars separated by white spaces. Representing such a structure in XSL Formatting Objects is easy, but a really challenging problem is to calculate bar widths starting from a string of symbols to encode. However, with XSLT, it becomes plausible. To confirm this claim, a stylesheet was designed to draw UPC/EAN barcodes.

UPC/EAN (Universal Product Code / European Article Numbering) is probably the most widespread barcode system: virtually every item found in stores bears a characteristic bars-and-digits label stamped on its back. EAN codes (8 and 13 digit) are used in all European countries, while UPC ones (8 and 12 digit) are more frequent in the North America. The encoding scheme for both barcode types is the same (12-digit UPC is a subset of 13-digit EAN).

Representation of digits by bars in UPC/EAN has some peculiarities:

An exhaustive description of the encoding algorithm can be found here.

No wonder that it took several hundred lines of XSLT code to get from a sequence of digits to the corresponding bar pattern. The result is a fairly complete XSL implementation of barcode drawing component. The stylesheet handles EAN codes (8-digit and 13-digit) and UPC codes (versions A and E). It provides for checksum calculation (including the trickiest UPC E case), and builds a complete pattern with numbers written at the bottom.

The stylesheet does more than just creating a sequence of bars: it also chooses the most traditional format for each type of code. There are subtle differences between EAN and UPC concerning digit grouping, bar lengths etc; all these are taken into account in the stylesheet.

Here is the stylesheet: barcode-EAN.xsl. Given below is a sample of its usage:

You can test it yourself:

  1. Take a bottle/can of your favourite drink out of the fridge and locate a barcode label on it;
  2. Create a new <barcode> item in bartest.xml;
  3. Copy all digits on the barcode label but the last one to the value attribute of a newly created item;
  4. Save bartest.xml and apply bartest.xsl to it by means of an XSLT processor (Saxon, Xalan, XT, ...);
  5. Convert the result to PDF by XEP. If you are not a XEP user, you can download an evaluation version here;
  6. Look at the result and compare it with the original label. If the two patterns are not equal, send a bug report to the author.

You can also try the barcode generator online: