A Hello, world XSL example

We start from an extended version of our memo.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified"
   vc:minVersion="1.0" vc:maxVersion="1.1">

<xs:element name="memo">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="from" type="Person"/>
            <xs:element name="to" type="Person" minOccurs="1" maxOccurs="unbounded"/>
            <xs:element name="subject" type="xs:string"/>
            <xs:element ref="content"/>
         </xs:sequence>
         <xs:attribute name="date" type="xs:date" use="required"/>
         <xs:attribute name="priority" type="Priority" use="optional"/>
      </xs:complexType>
   </xs:element>

    <xs:complexType name="Person">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="id" type="xs:ID"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:element name="content">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="para" minOccurs="1" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>

    </xs:element>

    <xs:element name="para">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element ref="link" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="link">
        <xs:complexType mixed="true">
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="linkend" type="xs:IDREF"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>

   <xs:simpleType name="Priority">
      <xs:restriction base="xs:string">
         <xs:enumeration value="low"/>
         <xs:enumeration value="medium"/>
         <xs:enumeration value="high"/>
      </xs:restriction>
   </xs:simpleType>

</xs:schema>

This schema allows a memo's document content to be structured into paragraphs. A paragraph may contain links either to the sender or to a recipient.

Figure 953. A memo document instance with an internal reference. Create comment in forum
<memo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="memo.xsd"
    date="2014-09-24" priority="high" >
  <from id="goik">Martin Goik</from>
  <to>Adam Hacker</to>
  <to id="eve">Eve Intruder</to>
  <subject>Firewall problems</subject>
  <content>
    <para>Thanks for your excellent work.</para>
    <para>Our firewall is definitely broken! This bug has been reported by
      the <link linkend="goik">sender</link>.</para>
  </content>
</memo>

Figure 954. Extracting the sender's name Create comment in forum
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

  <xsl:output method="text"/>

  <xsl:template match="/memo">
    <xsl:value-of select="from"/>
  </xsl:template>

</xsl:stylesheet>

Figure 955. Execution and Result Create comment in forum

Cli XSLT processor execution:

[goik@mupter Memoref]$ xml2xml message.xml  memo2sender.xsl
Martin Goik

The result is the sender's name Martin Goik. We may sketch the transformation principle:


We sketch the transformation principle:

Figure 956. XSL processor transforming XML using a stylesheet Create comment in forum

The executable xml2xml defined at the MI department is actually a script wrapping the Saxon XSLT processor. We may also use the Eclipse/Oxygen plugin replacing the shell command by a GUI as being described in the corresponding documentation. Next we closer examine the XSL example code:

Figure 957. Transformation syntax details Create comment in forum
<xsl:stylesheet ❶ xmlns:xsl ❷ ="http://www.w3.org/1999/XSL/Transform"
                version="2.0" ❸ >

  <xsl:output method="text" ❹/>

  <xsl:template ❺ match ❻ ="/memo">
    <xsl:value-of ❼ select ❽ ="from" />
  </xsl:template>

</xsl:stylesheet>

The element stylesheet belongs the the namespace http://www.w3.org/1999/XSL/Transform. This namespace is represented by the literal xsl. As an alternative we might also use <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform"> instead of <xsl:stylesheet ...>. The value of the namespace itself gets defined next.

The keyword xmlns is reserved by the Namespaces in XML specification. In pure XML the whole term xmlns:xsl would simply define an attribute. In presence of a namespace aware XML parser however the literal xsl represents the attribute value http://www.w3.org/1999/XSL/Transform. This value must not be changed! Otherwise a XSL converter will fail since it cannot distinguish processing instructions from other XML elements. An element <stylesheet> belonging to a different namespace http//someserver.org/SomeNamespace may have to be generated.

XSL is an evolving standard: The version number identifies subsequent code's conformance level.

The <xsl:output>'s method attribute specifies the type of output to be generated. It allows for defining indentation depths and/or encoding. Allowed method values are:

text

Ordinary text.

html

HTML markup.

xhtml

XHTML markup differing from the former by e.g. the closing /> in <img src="..."/>.

xml

XML code. This is most commonly used output type creating views or different dialects from a XML document instance.

A <xsl:template> defines the output that will be created for document nodes being defined by a selector.

The attribute match tells us for which nodes of a document instance the given <xsl:template> is appropriate. In the given example the value /memo tells us that the template is only responsible for memo nodes appearing at top level i.e. being the root element of the document instance.

A value-of element writes content to the XSL process' output. In this example the #PCDATA content from the element from will be written to the output.