XSL Transforms

Although XML is a precise and efficient method for storing and transmitting data, it is certainly not visually attractive and can be difficult for a person to read and understand. A technology called XSLT (eXtensible Stylesheet Language Transformations) exists that allows you to convert (transform) the data in an XML document into a more readable, browser-renderable format such as HTML. In a nutshell, XSLT allows you to view an XML data file as though it were a web page.

The basic steps involved in this process are:

  1. Write an XSLT transform for a specific type of XML file (e.g., invoice-v2009.2.xml).

  2. Associate the two files by adding a reference to the XSLT transform inside the XML file.

  3. Open the XML file in a browser; the browser executes the transform, converts the XML to HTML, and displays the result.

While the creation of XSLT transforms is a decidedly technical task, it is not particularly difficult, and can result in attractive and usable document displays. Your company can create transforms that include your own logo, watermark, fonts, and other information, and that cause the data in the "raw" XML file to be organized and displayed in a visual format of your own design.

The Basics

XSLT files process XML files by matching XML tags to mini-programs called templates, which change the XML tags into HTML while retaining the data inside the tags. For example, consider this XML snippet containing some information about a breakfast dish.

<?xml-stylesheet type="text/xsl" href="waffles.xsl"?>

<food>

<name>Belgian Waffles</name>

<price>$5.95</price>

<description>Two of our famous Belgian Waffles with plenty of real
maple syrup</description>

<calories>650</calories>

</food>

The first line of the XML snippet is the reference to the XSLT file to be applied, "waffles.xsl". A portion of that file, an XSLT template to transform that data into a browser-compatible format, might look like this.

<xsl:template select="food">

<p style="background-color:teal;color:white;font-weight:bold;">

<xsl:value-of select="name"/> -

<xsl:value-of select="price"/>

</p>

<p>

<xsl:value-of select="description"/>

(<xsl:value-of select="calories"/> calories)

</p>

</xsl:template>

The XML file then is opened in a browser. The XSLT reference causes the browser to load and process the template, and the generated HTML displayed in the browser then looks like this.

Belgian Waffles - $5.95

Two of our famous Belgian Waffles with plenty of real maple syrup (650 calories)

The template contains a series of XSLT commands that begin with "xsl:". The commands match the XML tags, replace them with HTML tags, and place the data inside the new tags so that it will all render nicely in a browser. To accomplish this, the template performs the following steps.

  1. Find the outside block tag ("food").

  2. Open an HTML paragraph with a teal background and white, bold text.

  3. Find the dish's name and output it inside the paragraph, followed by a dash.

  4. Find the dish's price and output it after the dash, then close the paragraph.

  5. Open a new paragraph with default text characteristics.

  6. Find the dish's description and output it inside the paragraph.

  7. Find the dish's price and output it, surrounded by parentheses, then close the paragraph.

This is, of course, a very simple example, but it is structured so that the processing sequence is fairly obvious. In fact, that XSLT processing sequence – match XML tags, change them to HTML tags, and then output the HTML tags and data – remains the same regardless of the complexity of the template.

A Real World Example

Let's look at another example, this time using a more realistic XML snippet, the Shipment Header from a NAMM Advanced Shipping Notice (ASN). Notice the XSLT reference on the second line.

 

 

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="asnpartial.xsl"?>

S2S3050_PO691634
2008-01-15T07:34:00

11111
2009-05-07
2009-05-10

0000000000001
Music Distribution Center
1 Central Ave
Melville
NY
11747
USA
US

0000000000001
Music Distribution Center
1 Central Ave
Melville
NY
11747
USA
US

112
Main Street Music
1 Main St

Any Town
CA
90210
USA
US

112
Main Street Music
1 Main St

Any Town
CA
90210
USA
US

Although the XML is a bit lengthy, it just contains the heading information (Document ID, Shipment ID, Shipped Date, and Estimated Delivery Date), and the basic seller and buyer information (Supplier, Ship From, Sold To, and Ship To). In a human-readable document, this information should probably appear in some sort of fixed format; perhaps as a list of the first group of items followed by a table containing the last four groups of items, like this.

Id:

2E944666-F10B-4B38-912A-28DE0B88D75D

Shipment Id:

xxxxxxx11111

Shipped Date:

2009-05-07

Estimated Delivery:

2009-05-10

Supplier:

0000000000001

 

Music Distribution Center

 

1 Central Ave

 

Melville, NY 11747

Ship From:

0000000000001

 

Music Distribution Center

 

1 Central Ave

 

Melville, NY 11747

Sold To:

112

 

Main Street Music

 

1 Main St

 

Any Town, CA 90210

Ship To:

112

 

Main Street Music

 

1 Main St

 

Any Town, CA 90210

In fact, this exact result can be achieved fairly easily using XSLT. Working in the same way as the waffles example above, the XSLT template must match specified XML tags and output them as HTML tags with their data values appropriately embedded. Look at this section of the XSLT file ("asnpartial.xsl", referenced in the XML file above) containing a template that processes the heading information.

<xsl:template match="ShipmentHeader">

<table border="0">

<tr>

<th style="font-size:15pt; text-align:right">Id:</th>

<td style="font-size:15pt; text-align:left"><xsl:value-of

select="Id"/></td>

</tr>

<tr>

<th style="font-size:15pt; text-align:right">Shipment Id:</th>

<td style="font-size:15pt; text-align:left"><xsl:value-of

select=" ShipmentId"/></td>

</tr>

<tr>

<th style="font-size:15pt; text-align:right">Shipped Date:</th>

<td style="font-size:15pt; text-align:left"><xsl:value-of

select="Shipped"/></td>

</tr>

<tr>

<th style="font-size:15pt; text-align:right">Estimated Delivery:</th>

<td style="font-size:15pt; text-align:left"><xsl:value-of

select="EstDeliver"/></td>

</tr>

</table>

<table border="1">

<tr>

<td style="width:400px">

<table border="0">

<tr>

<th>Supplier:</th>

<td><xsl:value-of select="Supplier/PartyId"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of select="Supplier/Name"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of

select="Supplier/Address/Address1"/></td>

</tr>

<tr>

<td></td>

<td>

<xsl:value-of select="Supplier/Address/City"/>

<xsl:text>, </xsl:text>

<xsl:value-of select="Supplier/Address/State"/>

<xsl:text> </xsl:text>

<xsl:value-of

select="Supplier/Address/PostalCode"/>

</td>

</tr>

</table>

</td>

<td style="width:400px">

<table border="0">

<tr>

<th>Ship From:</th>

<td><xsl:value-of select="ShipFrom/PartyId"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of select="ShipFrom/Name"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of

select="ShipFrom/Address/Address1"/></td>

</tr>

<tr>

<td></td>

<td>

<xsl:value-of select="ShipFrom/Address/City"/>

<xsl:text>, </xsl:text>

<xsl:value-of select="ShipFrom/Address/State"/>

<xsl:text> </xsl:text>

<xsl:value-of

select="ShipFrom/Address/PostalCode"/>

</td>

</tr>

</table>

</td>

</tr>

</table>

<table border="1" id="tbl">

<tr>

<td style="width:400px">

<table border="0">

<tr>

<th>Sold To:</th>

<td><xsl:value-of select="SoldTo/PartyId"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of select="SoldTo/Name"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of

select="SoldTo/Address/Address1"/></td>

</tr>

<tr>

<td></td>

<td>

<xsl:value-of select="SoldTo/Address/City"/>

<xsl:text>, </xsl:text>

<xsl:value-of select="SoldTo/Address/State"/>

<xsl:text> </xsl:text>

<xsl:value-of select="SoldTo/Address/PostalCode"/>

</td>

</tr>

</table>

</td>

<td style="width:400px">

<table border="0">

<tr>

<th>Ship To:</th>

<td><xsl:value-of select="ShipTo/PartyId"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of select="ShipTo/Name"/></td>

</tr>

<tr>

<td></td>

<td><xsl:value-of

select="ShipTo/Address/Address1"/></td>

</tr>

<tr>

<td></td>

<td>

<xsl:value-of select="ShipTo/Address/City"/>

<xsl:text>, </xsl:text>

<xsl:value-of select="ShipTo/Address/State"/>

<xsl:text> </xsl:text>

<xsl:value-of select="ShipTo/Address/PostalCode"/>

</td>

</tr>

</table>

</td>

</tr>

</table>

This may look like a lot of complex code, but notice that most of it is plain HTML – the HTML that we want the template to output to the browser. The XSLT commands ("xsl:") merely pick out specific pieces of XML data and place them into the HTML output at the appropriate places. To accomplish this, the template performs the following steps.

  1. Find the outside block tag ("ShipmentHeader").

  2. Open a table to contain the main heading information.

  3. Find the Id, ShipmentId, Shipped, and EstDeliver values and output them in four table rows with appropriate leading text, justified right and left within their table cells.

  4. Close the table.

  5. Open a new outer table to contain the two groups of seller information, "Supplier" and "Ship From".

  6. For the first group, open a "nested" table (a table within a table) inside the left-hand outer table cell.

  7. Find the name and full address values for the group and output them in four table rows with appropriate leading text on the first row. (Notice that the City, State, and PostalCode values are combined into one row, separated by commas and spaces.)

  8. Close the nested table.

  9. Repeat steps 6-8 for the other group in the right-hand outer table cell.

  10. Close the outer table.

  11. Open a new outer table to contain the remaining two groups of buyer information, "Sold To" and "Ship To".

  12. For the first group, open a "nested" table (a table within a table) inside the left-hand outer table cell.

  13. Find the name and full address values for the group and output them in four table rows with appropriate leading text on the first row. (Notice that the City, State, and PostalCode values are combined into one row, separated by commas and spaces.)

  14. Close the nested table.

  15. Repeat steps 12-14 for the other group in the right-hand outer table cell.

  16. Close the outer table.

As before, to see the person-friendly version of the data, the XML file is simply opened in a browser, which detects the XSLT reference, applies the template, and displays the result. Thus, by "reading" the XML code and data from a file and then "writing" the HTML code and data into the browser window, the XSLT template does in fact transform the information from one format to another.

Learning More

Of course, working XSLT files in a production environment are significantly more complex than these examples. While it is up to your technical staff to develop transforms that suit your corporate image using your own formatting, logos, and styles, NAMM provides additional information and maintains some sample XSLT transforms at http://www.namm.org/initiatives/b2b/docs/xslt-transforms-guide. On that page, you can open some XML files that use pre-written XSLT transforms to get an idea of what is possible, and you are welcome to download the XSLT files and modify them as you wish.

 

Note: You must be logged in to the NAMM site to access the XSLT transforms page. If you have an account, you may sign in here: /user; if you do not have an account, you may create one here: /user/register. NAMM web site accounts are free.

The screen shot below shows a sample invoice transformed by one of NAMM's example XSLT files. Notice that it uses header formatting similar to the ASN example above.

[image]

You can learn more about XSLT at the World Wide Web Consortium's (W3C) excellent "W3Schools" training site (http://w3schools.com/xsl/default.asp).