RU beehive logo ITEC dept promo banner
ITEC 325
2017spring
ibarland

homelectshws
D2Lbreeze (snow day)

xslt-intro
XSLT
value-of, for-each

Originally based on XML Visual Quickstart Guide by Kevin Howard Goldberg

XML

What is XML?

In the 80s, SGML was an obscure markup language; Tim Berners-Lee based HTML on it in 1990, which by the mid-90s was widely known. But because early browsers, trying to get market share, all worked hard to make sense of ill-formed HTML pages (tag soup), which in turn led people to learn and write bad HTML, the standardization process came to allow all sorts of awful shortcuts (e.g. you don't need to put attributes in quotes, or close your p tags, etc.).

In reaction to the sorry state of HTML, XML was a reiteration (and narrowing) of SGML.

As always: for your web pages, I recommend using all XML conventions when writing your HTML5. Even though you technically don't need to (say) close your p tags in HTML5, the XML requirements are all good ones which help clean data and interoperability.

Examples of XML documents

Here are some specific examples:

(As an aside: vector graphics vs. bitmap graphics: What are pros and cons of each? For sound, compare: Beethoven's Fifth on piano, vs. midi-with-simple-tones or midi-with-good-tones.)

Keeping data in XML format has several nice properties:

  1. It's a string-format which easily represents hierarchical information.
  2. It's human-readable (compared with a proprietary binary format often used otherwise).
  3. There are many nice tools for working with it: If you make your own information and store it as XML, you get all these tools and libraries for free.
  4. You have a default format for serializing your information.
It's worth noting that other formats also achieve this — notably, json (reasonable), and yaml (not preferred — too many surprising exceptions).

ch02 - XSLT basics

The next step in learning to use XML is understanding how to format these documents. The details for formatting XML documents was originally in a specification called XSLT, which stands for eXtensible Style Language Transformations. Chapters 2-4 explain how to use XSL to transform XML documents. The end result might be another XML document, or an HTML document (most common). You can transform an XML document into practically any document type.

Transforming an XML document means taking in one XML tree and producing another — a function from XML trees to XML trees. For example, consider the input

<my_children>
	<child>
		<name>Logan</name>
		<gender>M</gender>
		<age>7</age>
	</child>
	<child>
		<name>Rebecca</name>
		<gender>F</gender>
		<age>3</age>
	</child>
	<child>
		<name>Lee</name>
		<gender>F</gender>
		<age>2</age>
	</child>
</my_children>
An XSLT program might take this and return a new XML tree:
<html>
  <body>
    <h3>Some Kids</h3>
    <ul>
      <li>Logan, who is 7</li>
      <li>Rebecca, who is 3</li>
      <li>Lee, who is 2</li>
    </ul>
  </body>
</html>

Rather than write such a function in Java or a general-purpose programming language, XSLT is a domain-specific language, specifically invented to make these tree-transformations easy to write. XSLT can be used to reorder the ouput according to user established criteria, display only portions of the document, and more.

Overview

Building an XSL Style Sheet


One data file, many pages

youtube (3m09s):

Similar to how a web-page (data) can have a css-stylesheet directive (processing), XML data files have a xml-stylesheet tag, with what XSLT file processes them.

It's annoying, that the xml-stylesheet processing instruction should be in the same file as the raw XML data. What if you have one data file, and you want to use it to produce several different views/results? Alas, the usual solution is to fall back to a different technology: Have a php file which prints the xml-stylesheet line, and then require's the XML file:

// The file children.php:
<?xml-stylesheet type="text/xsl" href="children.xsl"?>
<?php
  require('children-data.xml');
?>
In fact, this might happen often enough that you choose to write a php util function — say, renderXMLWith([string] $xmlDataFile, [string] $xslTransformFile ) — which prints out these lines. (So the file being linked to (children.php) actually contains just two lines: requiring utils.php, and then a call to renderXMLWith).


Server-side XSLT

That is: Invoking XSLT via php.

So far, the XSLT we've seen is running client-side: the client requests the .xml file, it sees the <?xml-stylesheet processing instruction, requests the .xsl file, and then does the processing to create the output. This is reasonably well supported in all modern browsers.

Note: If you run locally, not using a web-server at all, and opening via Open File…: Firefox works, but Chrome won't7. You have to open Chrome with the command-line argument --allow-file-access-from-files: on Mac this can be done with /Applications/Google\ Chrome.app/contents/MacOS/Google\ Chrome --allow-file-access-from-files.

But of course, there's nothing inherent about doing the processing on the client. You can create a server-side .php page which, when requested, does the processing, to create the final html result:

Discussion:

You can do this in php as follows: First, omit the <?xml-stylesheet processing-instruction from the .xml file. Then, have a php file which does the following:

<?php
// Load XML file
$xml = new DOMDocument;
$xml->load('xml-database.xml');

// Load XSL file
$xsl = new DOMDocument;
$xsl->load('xsl-program.xsl');

// Configure the transformer
$proc = new XSLTProcessor;

// Attach the xsl rules
$proc->importStyleSheet($xsl);

echo $proc->transformToXML($xml);
?>
       
Source: www.w3schools.com/xsl/xsl_server.asp (This code uses php objects, hence the -> syntax for calling a method.)
a missed opportunity?:

Observe, in the last three lines, that you can can make one XSLTProcessor object which transforms many XML files, all using the same stylesheet.

If you're only serving a single web-page, this is usually moot. It would be useful if you have php prorams that pre-generate many pages. But I can't help wondering: which use-case is more common?

A built-in for helping with the former seems much more likely to be useful; as it is, we have to fall back to doing this manually.


1Although XML only became widespread in the 90s, old Lispers will look and say
S-expressions? Yes, of course they're an awesome data format!
Requring a tag at the start of every list? Sure, do that if you need to, I guess.
Repeat the tag at the end of every list? Well, that's sure redundant!
     
2Don't try editing the file w/o make a copy of the file and probably the .itl (real library file) as well.      
3 Remember, one of the XML requirements is that there is exactly one top-level tag.      
4 The reason for the lack of xsl:else is because it's a bit unclear where the else tag should be placed — conceptually it belongs beside the if tag, but requiring side-by-side tags is unlike any other instruction. Putting the else inside the if makes more sense, but even then the condition attributes now seem placed oddly. A more appropriate version might have an if tag with exactly two children: “then” and “else”. … hey now we've arrived back at what xsl:choose does, except we're limited to exactly-two! I guess they designed the choice tag correctly after all!      
5 Perhaps they should use an English term beside “if”; something like “when” or “unless”?      
6 In php it's no problem to have an expression whose result was inserted into the middle of an attribute. However, since XSLT is itself written in XML, and XML of course doesn't allow opening a tag in the middle of an attribute, the syntax physically precludes putting xsl:select (etc.) expressions in the middle of an attribute.      
7 When rending a local file:// URL, Chrome's XSLT engine sees the stylesheet's URL (if also local) as a security risk, and does not open it by default.      

homelectshws
D2Lbreeze (snow day)


©2017, Ian Barland, Radford University
Last modified 2017.Apr.21 (Fri)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.