Content:
1. XML - eXtensible Markup Language
2. XLST - eXtensible Stylesheet Language Transformation
   - XSLT file frame
   - Reference from XML to XSL
   - Output all XML data - xsl:apply-templates
   - Output single node type - xsl:value-of
   - Embedded xslt
   - Conditional processing - xsl:if
   - Conditional processing - xsl:choose
   - Selecting specific elements and sorting - xsl:for-each xsl:sort
   - XML "procedures"


Code example (open .xml in web browser and notepad)

1. XML - eXtensible Markup Language

XML document allows storing hierarchical data. The example below demonstrates 2 people from a database.
XML format consists of:
elements, e.g. person, firstName
attributes e.g. id
More about XML at w3schools

XML
<people>

  <person id="1">
    <firstName>John</firstName>
    <lastName>First</lastName>
    <department>IT</department>
  </person>
  
  <person id="2">
    <firstName>Paul</firstName>
    <lastName>Second</lastName>
    <department>Finance</department>
  </person>

</people>                                                                     


2. XLST - eXtensible Stylesheet Language Transformation

XLST allows transforming any valid XML document to a different format, most often an HTML document or it could be csv text data file or a SQL script that will insert data into a SQL database. These web pages are completely generated from XML files.

More about XSL on w3schools or reference on zvon.org

XSLT file frame

XSL document needs to be wrapped in a frame like below

XML
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
   <!-- content -->
</xsl:stylesheet>

Reference from XML to XSL

In order to transform an XML document it needs to refer to an XSL style

XML
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="myStyle.xsl" type="text/xsl"?>
<people>
    <!-- content -->
</people>
This does not work by default in Chrome. You have to start Chrome with "--allow-file-access-from-files" http://stackoverflow.com/questions/2981524/how-can-i-make-xslt-work-in-chrome

Output all XML data - xsl:apply-templates

To process (output) data from XML file you need to use apply-templates command, which in the example below

XML
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" encoding="utf-8"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

</xsl:stylesheet>
will process traverse all the nodes and output: JohnFirstITPaulSecondFinance
You can see the output if you open the xml file on your web browser.

You can see that only xml elements were outputted, not xml attributes.

Output single node type - xsl:value-of

If you need to modify output of a specific element use value-of command
The example below will output department in bold and break new line after each person.

XML
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" encoding="utf-8"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

<xsl:template match="department">
  <b><xsl:value-of select="."/></b><br/>
</xsl:template>

</xsl:stylesheet>
Output:
JohnFirstIT
PaulSecondFinance

select="." means that you select current value of the node. If you match person instead of departemtn then you if you use select="department" you will achieve the same output.

XML
<xsl:template match="person">
  <b><xsl:value-of select="department"/></b><br/>
</xsl:template>
an attribute could be accessed as select="@id"

Embedded xslt

W3.org allows embedding xslt template in xml file.

This is supported by Chrome or Mozilla. It does not work in IE or Edge. File encoding must be UTF-8 in order to work in Google Chrome.

XML
<?xml version="1.0"?>

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

<!DOCTYPE persons [
<!ATTLIST xsl:stylesheet
  id    ID    #REQUIRED>
]>

<persons>

  <xsl:stylesheet version="1.0"
                  id="stylesheet"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output method="html"/>
    
    <!-- skip transfornimg stylesheet elements -->
    <xsl:template match="xsl:stylesheet" />
  
    <xsl:template match="/">
      <html>
        <body>
          Works in Chrome (v55) only
          <xsl:apply-templates/>
        </body>
      </html>
    </xsl:template>
    
    <xsl:template match="person">
      <h1>Person</h1>
      First name: <xsl:value-of select="@firstName" />
      Last name: <xsl:value-of select="@lastName" />
    </xsl:template>
  
  </xsl:stylesheet>

  <!-- data -->
  <person firstName="John" lastName="First" />
  <person firstName="Paul" lastName="Second" />
</persons>

Conditional processing - xsl:if

If you need to process different nodes differently, you can use xsl:if. The example below will display people from IT department in Italic.

XML
<xsl:template match="person">
  <xsl:if test="department='IT'>
     <xsl:value-of select="department"/>
  <xsl:if/>
</xsl:template>

Conditional processing - xsl:choose

The example above will display only people from IT department. In order to display all, we can use xsl:choose

XML
<xsl:template match="person">
    <xsl:choose>
     <xsl:when test="department='IT'">
       <i><xsl:apply-templates /></i>
     </xsl:when>
     <xsl:otherwise>
       <xsl:apply-templates />
     </xsl:otherwise>    
    </xsl:choose>
</xsl:template>

Selecting specific elements and sorting - xsl:for-each xsl:sort

The example above will iterate over all (defined by //) person elements select in order of id and output lastName. Oppose to apply-templates, for-each will iterate only on one level. It will ignore deeper levels like child elements

XML
<xsl:template match="/">
  <html>
    <body>
      <xsl:for-each select="//person">
        <xsl:sort select="@id"/>
        <xsl:value-of select="lastName"/>
      </xsl:for-each>
    </body>
  </html>
</xsl:template>

XML "procedures"

In order avoid copy-pasting code and maintaining the same code in multiple places, it is possible to reuse templates and call them similar as procedure in a common programming language.

The example below shows how to create HTML link "procedue and call it". You would usually replace content of select="http://mysite" with data from currently processed node.

XML
<!-- caller -->
<xsl:call-template name="CreateLink">
  <xsl:with-param name="reference" select="http://mysite" />
  <xsl:with-param name="title" select="Go to my site."/>
</xsl:call-template>

<!-- "procedure" -->
<xsl:template name="CreateLink">
  <xsl:param name="reference" />
  <xsl:param name="title" />

  <xsl:text disable-output-escaping="yes">&lt;a href="</xsl:text>
  <xsl:value-of select="$reference" />
  <xsl:text disable-output-escaping="yes">"&gt;/xsl:text>
  <xsl:value-of select="$title" />
  <xsl:text disable-output-escaping="yes"&lt;/a&gt;</xsl:text>
</xsl:template>