|
home—lects—exams—hws
breeze (snow day)
Originally based on XML Visual Quickstart Guide by Kevin Howard Goldberg, and notes therefrom by Jack Davis (jcdavis@radford.edu).
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 much, much more.
<xsl:for-each select="nodeSpec"> results... </xsl:for-each> |
<?xml-stylesheet type="text/xsl" href="foo.xsl"?> |
Once the browser has constructed the XML data tree, it then transforms that XML tree using the XSLT instructions, yeilding a new tree. The transformation rules are called “templates”; they correspond to functions in a programming language — a function which is given an XML node as input, and returns a (new) XML node.
(Note: usually the output happens to be XHTML, but it can in theory be any XML.)
A particular transformation (“template”)
looks at one node of the input tree [including its subtree],
and produces a (sub)tree to include in the overall output.
In the my_children example above,
there might be one “helper” XSLT template which,
given a
In our context, it's the browser which invokes the XSLT processor, and the result is html. (The XSLT is being run client-side.) However, that's not required — XSLT can produce any XML output, and the XSLT processing can be run stand-alone.
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
</xsl:stylesheet> |
<xsl:template match="/" > <!-- rule for root-element here --> </xsl:template> |
Note:If you do not include a root template in the XSLT stylesheet, a root template built in to XSLT will be used (typically not what you want).
After running the XSLT program, we have newly-built XML tree;
the very last step is to flatten that tree back to a string
and print it as output.
We can use the
In 95% of all cases, our resulting XML tree is HTML, and so we'll include
<xsl:output method="html"/> |
Note that
Example:
Putting the above together, we'll make a trivial XSLT program
which ignores its input entirely, always generating the same, constant output page:
lect11c-ch02-constant.xml
lect11c-ch02-constant.xsl
The body of the loop is XSLT,
where the implicit-root of any relative XPATHS is
one of the things selected by the
Note how the syntax of
<p> This person is <xsl:choose> <xsl:when test="height > 200"> extremely </xsl:when> <xsl:when test="height != 0"> <xsl:value-of select="height"/> cm </xsl:when> <xsl:otherwise> unknown </xsl:otherwise> </xsl:choose> tall. </p> |
<xsl:if test="boolean expression"> <!-- other XSLT statements statements --> </xsl:if> |
<xsl:if test="name[@language='English']"> It's called <xsl:value-of select='name'>. </xsl:if> |
observation: Placing thexsl:sort tag as the first-child inside the loop's body is definitely odd. It would be more natural to have a stand-alonesort tag which takes the XPATH of the nodes to sort, and returns a “list” of the sorted nodes seems that the loop's control-flow should all be set via attributes. Alas, they didn't ask me when designing it. (Also, there are XPATH issues since thexsl:for-each is working on the parent, but the sort'sselect expression is relative to a child.)
<xsl:attribute name="att_name"> <!-- Here, specify the value of the new attribute. Of course, you can use any XML: literal, or and XSLT instructions. This body gets spliced into the enclosing tag (!) --> </xsl:attribute> |
Suppose we want each Wonder to be a link —
that is instead of the plain text “
<a> <xsl:attribute name="href"> #<xsl:value-of select="../wonder/name" /> <!-- link-target --> </xsl:attribute> <xsl:value-of select="../wonder/name" /> <!-- link-text --> |
(Like
The root template is the first thing processed in an XSLT style sheet. XSLT allows you to create more templates than just the root template. This allows you to create different sets of processing rules to apply to different parts of the XML document.
One of the main benefits of using templates is the ability to reuse a template for other nodes in your document. In the same way that one can use functions in most programming languages, you would create a template, and simply apply that template whenever necessary. This eliminates the need to repeat the same processing instructions.
In our ongoing example: We have been putting the non-english name in parentheses and italics. Suppose we want to do that throughout, consistently, and make it easy to maintain any changes or tweaks to this decision. We can define a template to process non-English name nodes, and then apply it in different contexts. (E.g. if there are tags for “newspaper”, we could apply the same template for non-English names there.)
<!-- Define the function --> <xsl:template match="name[@language!='English']"> (<em><xsl:value-of select="."/></em>) </xsl:template> |
<xsl:apply-templates select="ancient_wonders/wonder"> <xsl:sort select="height" order="descending" data-type="number" /> </xsl:apply-templates> |
1 Remember, one of the XML requirements is that there is exactly one top-level tag. ↩
2
The reason for the lack of
3
Perhaps they should use an English term beside “if”;
perhaps
4
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
home—lects—exams—hws
breeze (snow day)
©2011, Ian Barland, Radford University Last modified 2011.Dec.13 (Tue) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |