WEEK 8: XSL - eXstensible Stylesheet Language

.
Reading Assignments
BOOK PAGES
XML in easy steps CH 7

LINKS TO XML RELATED SITES

  1. XML.COM
  2. MSDN'S XML DEVELOPER SITE
  3. IBM's XML WEBSITE
  4. IBM'S ALPHAWORKS WEBSITE
  5. W3 Schools XML Tutorial
  6. Kickstart XML Tutorial
MATCHING ELEMENTS WITH XSL
  1. Matching Root Node XSL, eXtensible Stylesheet Language, is an XML document and it is not really a stylesheet like CSS (Cascading Style Sheet). An XSL document is more like a map or a filter. It allows us to create a new document by mapping the data from an existing XML document to another XML or HTML document. For now, the conversion between XML to HTML would be the focus of our topic.

    XSL, works by matching tags and acting on the elements that was matched. The first part of the document that we need to matching is the root node whose child is: <xsl:template match="/">. Afterward the parser moves down our XML document structure.

    In our example we have created a simple one element XML document, were we have parsed the document root and have told the XSL parser to return everything (their values) within the root elements (<xsl:value-of />). In this case, it is just the word "hello".

    Click here To view the XSL

  2. Value Of Everything The "value-of" tag will return the value within any tag inside the root element. In this case, our root tag is "student" and within student we have placed "first_name" and "last_name". As you can see the content within these tags are return and as the result are displayed as one contiguous text.

    It is worth knowing that the element "value-of" is part of the "xsl:" which as you recall is the name space. If you have ever programmed in Java or JavaScript you have inevitably used the "object.property" syntax. If we were to follow that syntax we would have written "xsl.value-of".

    Click here To view the XSL

  3. Matching Other Elements In above examples we told the parser to begin at document root and return the data inside all the tags as it parsed ( walked down the document tree) our document. What we could instruct the parser to do instead, is to match specific tags and perform differ net action base on the match. In this example we have instruct the parser to only return the data within "first_name".

    The first thing that should be noticeable is the use of "apply-templates select="//first_name" " where we had "value-of" . This syntax is instructing the parser to only match for "first_name" and upon matching it search and apply another set of "template" instructions. For now lets ignore "//" in the "//first_name" we will comeback to later. In the next template set there is pattern for matching the "first_name" (<xsl:template match="first_name">)with instructions for displaying the data inside the "first_name", "value-of". Note that we are only able to see the first name.

    Click here To view the XSL

  4. Displaying Last Name To display the last name we need to provide another template set to match "last_name". But first we have to instruct the parser to search for the template by "apply-templates select="//last_name" ".

    Click here To view the XSL

  5. Now for some tricky stuff!

    We can reverse the order of the elements in the XML file, and reverse the order of the rendering in the XSL file:

    Look at XML file xsl4a.xml and XSL file xsl4a.xsl - look at the order of first_name and last_name in both .xml and .xsl documents

    Look at XML file xsl4b.xml and XSL file xsl4b.xsl - now we reverse the order of the named templates in the stylesheet - no difference!

    Look at XML file xsl4c.xml and XSL file xsl4c.xsl - now we reverse first_name and last_name in the .xml document - and no difference!

    Look at XML file xsl4d.xml and XSL file xsl4d.xsl - now we keep first_name and last_name reversed in the .xml document, and then reverse first_name and last_name in the named templates in the .xsl document - and still no difference in the order of first_name and last_name!

    Look at XML file xsl4e.xml and XSL file xsl4e.xsl - now we go back to the original files in 4a above, but reverse the order of the apply-templates select statement. Now the order of the output is reversed!

    Look at XML file xsl4f.xml and XSL file xsl4f.xsl - we keep the pattern from 4e above, but reverse the template match statements. We still have last_name appearing before first_name. What XSL statement appears to be key? (hint: see 4e above).

    Look at XML file xsl4g.xml and XSL file xsl4g.xsl - with first_name and last_name reversed in the .xml document, otherwise a repeat of 4e.

    Look at XML file xsl4h.xml and XSL file xsl4h.xsl - with first_name and last_name reversed in the .xml document, otherwise a repeat of 4f.

    Please study these carefully *before* asking (in person or online) questions about how this all works. It's all about the 'template select', not the 'template match' statements, as that affects the order in which the display is rendered. See 4e.

  6. Apply Template To All The Children In the above examples we had to specify at the root node <xsl:template match="/"> the tags that the parser can only match. If a tag has numerous children, then this could become a laborious effort. To instruct the parser to search for all the child tags we could simply remove the "select" attribute of the apply-templates tag, "select="SOME PATTERN".

    First we have some explaining to do: The first instruction in the XSL, <xsl:template match="/"> does not matches the root tag (same as root element). What it matches is the root node. The root element is the child of the root node. Until now, we did not have to care much about this technical detail, as every tag is a descendent of the root node. However, we now need to instruct the parser to search for all the direct children of the "student" tag ( the document root element) which is the child of the root node, "/" itself.

    Therefore, we have given the instruction to the root node to search and match "student" then inside the "student" templates there is instruction to search for all the template of its children, "apply-templates".

    Click here To view the XSL

PATTERN MATCHING
  1. Wild Card (*) XSL, provides a powerful syntax for matching elements. You can not have pattern matching without a wild card. In this example instead of having two separate template sets for both "first_name", and "last_names" we are having one that matches both of them, <xsl:template match="*">

    Click here To view the XSL

  2. First Descendent (/) If we need to specify the first descendent we can use the "/" in our pattern syntax. Our XML document has to different "id" tags. One, for the student, and the other for the "homework". In our XSL document we have specified the path "/students/student/id", which indicates a direct descendency from the root node (/) to the root element (students), to the first child of "students" (student) and finally to the "id" which is its direct descendent. Please note the value display on the screen.

    Click here To view the XSL

  3. Recursive Descent (//) What if we had desired to return all the "id" element descending from the "student" tag, regardless of their direct descendency. In this example we have used "select="/students/student//" " instead and as the result of "//" following the "student" tag, all descendent of "student" is matched. Please note the value displayed as contrast to the previous example.

    Click here To view the XSL

  4. Current Context (.) This operator indicates current node. In this example we are only showing the "id" tag under the "homeworks". In this example we have first made a pattern match to the "homeworks" and that point we have instructed the parser to recursively search under this node ".//". Note, we are only getting the "id" under the "homeworks".

    Click here To view the XSL

  5. Attribute Path Operator (@) So far our patterns have only been matching based on tags. Now, we are able to match base on the attribute. In this example our " select="@class" " returns the value of class attribute.

    Click here To view the XSL

XML TO HTML
  1. Adding HTML One of the uses of XSL is for converting XML documents to HTML in order to allow viewers with non-XML browsers to view the website. Converting XML to HTML follows the pattern matching which we have been doing with an exception of adding HTML tags around the "value-of" tags.

    One important thing that we need to remember is that XSL is an XML document, therefore all of our HTML tag must follow the well-formedness rules of XML document: Each tag needs to be closed or be treated as an XML empty tag ("<BR />).

    In this example we have wrapped the "HTML" and "BODY" around the root node. Since these tags are not visible by themselves we added the text "CLASS" centered on the page as visible indication.

    Click here To view the XSL

  2. Adding H1 In this example we have taken the attribute value of our class and have used the "H1" and "CENTER" tag to display our class name.

    Click here To view the XSL

  3. Displaying with P In this example we have added a few more records and are placing them all together inside a "P" tag.

    Click here To view the XSL

  4. FOR EACH This example is identical as above except we are using the "xsl:for-each" looping element. Our XSL instructions will loop bases on the number of students, "xsl:for-each select="/students/student". As the result with each iteration the students record are wrapped inside a pair of "P" tags.

    Click here To view the XSL

  5. TABLES Now, we have taken our records and instead of using "P" tags, every student is in a separate row "TR".

    Click here To view the XSL

  6. TABLES Now, we have taken our records and instead of using "P" tags, every student is in a separate row "TR".

    Click here To view the XSL

  7. TABLES Now, every student is in a separate row "TR", but we use templates this time.

    Click here To view the XSL

  8. NESTING TABLES We can go one step further and apply the "for-each" looping syntax inside another one (this is what programmers call nested loops) to create a nested table of data. This example requires a bit of think and digesting.

    Click here To view the XSL

  9. LINKS and IMAGES This example requires a bit of thought and digesting. The key for both of these is to create a template based on the tag name; in the LINK example, the template is "title/html:a". Then, in the template definition, you need to describe a standard link in terms of the tags and attributes used in the XML file.
    <a> --- the html open link tag
    <xsl:attribute name="href"> --- the html link href attribute
    <xsl:value-of select="./@href" /> --- value of the the link attribute used in the xml file
    </xsl:attribute> --- closes the link href attribute
    <xsl:value-of /> --- the link value used in the xml file
    </a> --- the close link tag
    The image template is constructed in a similar way. We leave it as further exercise for you to decide how to create a template for an image link.....
    Click here To view the XSL

    A very late edition (this is very rough) is a method of creating links and images without the html namespace. Try this approach first. Look at roses_xsl.xml, roses.xsl, using rose.jpg, or the whole roses_xsl.zip archive. Again - this is very rough.

    Last is another example of creating links and images without the html namespace. This includes adding an image, a website link, and an email link. Look at formatting.xml, formatting_xsl.xml, and formatting.xsl, using metaman.jpg, or the whole formatting.zip archive.

  10. Adding Style (CSS) You should be aware that HTML will not recognize the XML tags and will not be able to correctly apply CSS styles to render those tags. In order to implement them, it is necessary to extend the CSS definitions by appending a "span.tag" to the existing definition. Thus, "book { ... }" becomes "book, span.book { ... }". In order to use them, we use the XSL sheet to add the span tags. So, for instance:
    <span class="blurb">
    <xsl:value-of select="blurb" />
    </span>

    Click here To view the XSL

    Click here To view the CSS

More Example Files - Now that you have worked through the tutorials, you would like to see some elegant examples. (Right click to download the links).

The first is an artistic and colorful rendering by Tal Broda address_book_xsl.xml and address_book.xsl.

The second is a more conservative style which is also very elegant, and adds links to both the email address and to the website links. This was created by Alex Ivanov. It is shown in address_book_xsl_1.xml and address_book_1.xsl which uses the <html:a> prefixed element. An example of the same files which do not use an <html:a> prefix are shown in address_book_xsl_2.xml and address_book_2.xsl (the better approach).

HOMEWORK