I have an RSS feed that changes regularly (same format, different data) and I need to apply a transform to it to get a list of items from it using tags. The problem is, I never know what position the item with the correct tags will be in. Example: If I was generating a carousel from this for a page that is related to "theory" I'd need to pull the "items" from the list of items in the RSS that have the relevant tags, then append the class "active" to the element with the class "newsitem row item".
I realize I could do this extremely easily with jQuery -- >
$(".newsitem.row.item").first().attr("class","newsitem row item active");
But, if possible, I'd like to save a step and generate the HTML with the active class in place.
<rss xmlns:atom=" ... " version="2.0">
<channel>
<title>Latest News</title>
<link>http://...</link>
<description>Latest News</description>
<atom:link href="..." rel="self"/>
<language>en</language>
<copyright>Copyright (c) 2015</copyright>
<lastBuildDate>Sat, 25 Apr 2015 23:39:40 -0500</lastBuildDate>
<item>
<title>TITLE FOR FIRST ITEM</title>
<link>LINK FOR FIRST ITEM</link>
<description>DESCRIPTION</description>
<pubDate>Sat, 25 Apr 2015 23:39:40 -0500</pubDate>
<guid>GUID</guid>
<category>gallery</category>
<category>events</category>
<item>
<title>TITLE FOR NEXT ITEM</title>
<link>LINK FOR NEXT ITEM</link>
<description>DESCRIPTION ...</description>
<pubDate>Tue, 10 Mar 2015 20:59:12 -0500</pubDate>
<guid>GUID ...</guid>
<category>architecture</category>
<category>class acts</category>
<category>competitions</category>
<category>feature</category>
<category>global college</category>
<category>graduate work</category>
<category>health systems & design</category>
<category>honors</category>
<category>rss</category>
<category>wellness</category>
</item>
...
<item>
<title>TITLE FOR THE NTH ITEM</title>
<link>LINK FOR THE NTH ITEM</link>
<description>DESCRIPTION ...</description>
<pubDate>Tue, 10 Mar 2015 20:52:45 -0500</pubDate>
<guid>GUID ...</guid>
<category>applied creativity</category>
<category>gallery</category>
<category>coa gallery</category>
<category>graduate work</category>
<category>research</category>
<category>rss</category>
<category>technology</category>
<category>theory-philosophy</category>
<category>video</category>
<category>visualization</category>
</item>
</channel>
</rss>
My code is:
<xsl:stylesheet xmlns:xsl="..." version="1.0">
<xsl:template match="/">
<div class="row">
<div class="col-md-12 banner_image vanish">
<div class="carousel newsitems slide" data-carousel-delay="8000" id="banner-latest-85695">
<div class="carousel-inner">
<xsl:apply-templates select="//item"/>
</div>
<a class="carousel-control left" data-slide="next" href="#banner-latest-85695" title="Previous News Item"></a>
<a class="carousel-control right" data-slide="next" href="#banner-latest-85695" title="Next News Item"></a>
</div>
</div>
</div>
</xsl:template>
<xsl:template match="item|text()">
<xsl:if test="category[contains(text(),'theory')]">
<div class="newsitem row item">
<xsl:if test="position() = ?"> <!-- what position test do I use? -->
<xsl:attribute name="class">newsitem row item active</xsl:attribute>
</xsl:if>
<div class="image span">
<img>
<xsl:attribute name="src">
<xsl:value-of select="carousel"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="title"/>
</xsl:attribute>
</img>
</div>
<div class="details span">
<h2>
<a>
<xsl:attribute name="href">
<xsl:value-of select="link"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</a>
</h2>
<div class="publication-date">
<span>posted</span>
<xsl:value-of select="pubDate"/>
</div>
<div class="description">
<xsl:value-of select="description"/>
</div>
</div>
</div>
</xsl:if>
</xsl:template>
This works if the first item in the rss feed contains the tag I am looking for. What am I overlooking here?
** EDITED TO CLARIFY
LINKS REPLACED WITH "..."
Your question is not entirely clear. If you want to select item (or items) by the "tag" it contains, you should do something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<div>
<xsl:apply-templates select="rss/channel/item[tag2]"/>
</div>
</xsl:template>
<xsl:template match="item">
<div>
<span>
<xsl:value-of select="value"/>
</span>
</div>
</xsl:template>
</xsl:stylesheet>
Here, we're looking for item/s with a child element named tag2. Applying this to the following test input:
<rss>
<channel>
<item>
<tag1/>
<value>100</value>
</item>
<item>
<tag2/>
<value>200</value>
</item>
<item>
<tag2/>
<value>201</value>
</item>
<item>
<tag3/>
<value>300</value>
</item>
</channel>
</rss>
produces the result:
<?xml version="1.0" encoding="UTF-8"?>
<div>
<div>
<span>200</span>
</div>
<div>
<span>201</span>
</div>
</div>
Related
I have a set of XML files where place names (in divergent historic spelling) are tagged as
<place>: cf. sample file. The place tag also contains the attribute link, whose value is a hyperlink to a World Historical Gazetteer page, e.g.:
<place name="Wien" type="place_of_issue"
link="http://whgazetteer.org/places/12346175/portal">Wien</place>
Converting the XML files to HTML with XSLT, I want every such tag in the text to be replaced by a hyperlink <a href>, linking to the same WHG URL.
A minimal version of my XSL based on Michael Hor-257k's answer is:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<!-- Jekyll statement -->
---
<xsl:for-each select="source/metadata/digital_surrogate">
layout: page
title: <xsl:value-of select="#filename"/>
permalink: /<xsl:value-of select="#filename"/>/
exclude: true
---
</xsl:for-each>
<!-- Get transcription with links -->
<div class="flex-container">
<div><p><strong>Transkription:</strong></p>
<p><xsl:apply-templates select="//div">
</xsl:apply-templates>
<!-- include WHG links -->
<xsl:for-each select="//place">
<p>Genannte Orte im World Historical Gazetteer:</p>
<a href="{//place/#link}" target="_blank">
<xsl:value-of select="."/>
</a><br/>
</xsl:for-each>
</p><br/>
</div>
</div>
</xsl:template>
</xsl:stylesheet>
This at least correctly displays all place names mentioned in the correct order, with correct WHG links and correct names:
Wien
Maintz
Wien
However, the links still appear below the transcription, not within.
My desired HTML output would be:
<div class="flex-container">
<div>
<p><strong>Transkription:</strong></p>
<p>
Wir Vorsteher und gesamte
Meister des ehrsamen Handwerks der bürgerl:[ichen] Tischlern in der K:[aiserlich]
K:[öniglichen] Haubt = und Residenz Stadt Wien (beglaubigen) hiermit,
daß gegenwertiger Tischlergesell, Namens Georg
Gramer von Maintz - -
[etc.]
</p>
</div>
</div>
I am guessing that instead of:
<xsl:variable name="urlPlace">
<xsl:value-of select="#link"/>
</xsl:variable>
<xsl:apply-templates select="//place"/>
you want to do:
<a href="{#link}" target="_blank">
<xsl:value-of select="."/>
</a>
Untested, because no example to test with was provided.
--- added ---
See if you can use this as your starting point:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/source">
<html>
<body>
<xsl:apply-templates select="content/body/div"/>
</body>
</html>
</xsl:template>
<xsl:template match="div">
<p>
<xsl:apply-templates select="text"/>
</p>
</xsl:template>
<xsl:template match="place">
<a href="{#link}" target="_blank">
<xsl:value-of select="."/>
</a>
</xsl:template>
</xsl:stylesheet>
To understand this and adapt it to your needs, you will need to study XSLT's processing model: https://www.w3.org/TR/1999/REC-xslt-19991116/#section-Processing-Model
If you want to transform a place element like <place name="Wien" type="place_of_issue" link="http://whgazetteer.org/places/12346175/portal">Wien</place> into an HTML a element use a template
<xsl:template match="place">
<a href="{#link}">
<xsl:value-of select="."/>
</a>
</xsl:template>
Write templates for the transformation of other elements like the ancestors of the places and make sure these templates process child nodes with <xsl:apply-templates/>.
That way the structure and order of the input should be preserved, only that you have HTML in the output reflecting the semantic XML elements you have in the input.
The two previous answers helped me understand the nesting rules in XSL that I wasn't familiar with.
So here is the full XSL that does exactly what I want:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<!-- BESCHREIBUNG, BILD UND TEXT AUF "SOURCE" EBENE -->
<xsl:template match="source">
<!-- Jekyll statement --> --- <xsl:for-each select="metadata/digital_surrogate">
layout: page title: <xsl:value-of select="#filename"/> permalink: /<xsl:value-of
select="#filename"/>/ exclude: true --- </xsl:for-each>
<!-- Metadaten -->
<xsl:for-each select="metadata/source_description">
<h3>Ausstellungsort: <xsl:value-of select="#place"/></h3>
<h3>Ausstellungsdatum: <xsl:value-of select="#date"/></h3>
</xsl:for-each>
<xsl:for-each select="edition">
<h4 align="center">ediert von: <xsl:value-of select="editors/#name"/></h4>
<h4 align="center">zuletzt bearbeitet: <xsl:value-of
select="transcription_info/#last_revision_date"/></h4>
</xsl:for-each>
<br/>
<xsl:for-each select="metadata/digital_surrogate">
<xsl:variable name="urlVar">
<xsl:value-of select="#URL"/>
</xsl:variable>
<img src="{$urlVar}" valign="top"/>
</xsl:for-each>
<!-- HTML-Flex-Container für Digitalisat und Inhalt -->
<div class="flex-container">
<div>
<p>
<strong>Graphische Elemente:</strong>
</p>
<p>
Art des Siegels: <xsl:value-of select="metadata/source_description/#seal"/>
Sonstiges: <xsl:for-each select="visual_element"/>
</p>
<br/>
</div>
</div>
<hr/>
<div class="flex-container">
<div>
<p>
<strong>Transkription:</strong>
</p>
<p>
<xsl:apply-templates select="content/body/div"/>
</p>
</div>
<div>
<p>
<strong>Übersetzung:</strong>
</p>
<p>
<xsl:apply-templates select="translation"/>
</p>
<br/>
</div>
</div>
</xsl:template>
<!-- WHG LINKS AUF EBENE DIV UND TEXT -->
<xsl:template match="div">
<p>
<xsl:apply-templates select="text"/>
</p>
</xsl:template>
<xsl:template match="place">
<a href="{#link}" target="_blank">
<xsl:value-of select="."/>
</a>
</xsl:template>
</xsl:stylesheet>
For the below simplified transformation sheet, I'd like to add the following functions:
For "Turnover 2019" and "Turnover 2020" I'd like to get the values below 1mio in a red badge and over 1mio in a green badge. I tried to implement this for "Turnover 2019", however I just get a blank output. The problem seems to be with the <xsl:if test="...">-part, as I do get the correct value if I just enter <xsl:value-of select="key('keyToCreditcard', id)/turnover_2019"/> (see "Turnover 2020").
For "Total Turnover" I need to sum up the values of "Turnover 2019" and "Turnover 2020". How do I do that?
XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyToPerson" match="person" use="id"/>
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<xsl:for-each select="data/persons/person">
<xsl:if test="turnoverYear1 < 1000000">
<span class="badge bg-warning mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:if test="turnoverYear1 > 999999.99">
<span class="badge bg-danger mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:value-of select="key('keyToCreditcard', id)/turnoverYear2"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Input:
<data>
<persons>
<person>
<id>1</id>
<name>Jeramie Bischoff</name>
<city>Luzern</city>
<birthdate>04/16/1951</birthdate>
</person>
</persons>
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnoverYear1>952411.33</turnoverYear1>
<turnoverYear2>6135840.0</turnoverYear2>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
</data>
Expected Output:
Name:Jeramie Bischoff
City: Luzern
birthdate: 04/16/1951
Card Type: Visa
Card Number: 4041592612048990
Turnover 2019: 952411.33
Turnover 2020: 6135840.0
Total Turnover: 7088251.33
Based on your sample XML, a good approach would be to split things up into multiple templates.
One to handle creating the basic HTML document structure (match="/"), one to handle <person> elements, one to handle the turnover badges, and so on. In general it's beneficial to prefer <xsl:apply-templates> over cramming everything into a single template with a bunch of nested <xsl:for-each>.
Since you have an <xsl:key> that links person IDs to credit cards, use that to fetch the <creditcard> into a variable ($cc) and work with it.
<xsl:output method="html" indent="yes" />
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<html>
<!-- ... -->
<xsl:apply-templates select="data/persons/person" />
<!-- ... -->
</html>
</xsl:template>
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<div>
<xsl:text>Turnover 2019: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear1" />
</div>
<div>
<xsl:text>Turnover 2020: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear2" />
</div>
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="$cc/turnoverYear1 + $cc/turnoverYear2" />
</div>
</div>
</xsl:template>
<xsl:template match="turnoverYear1|turnoverYear2">
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</xsl:template>
which results in
<html>
<div class="person">
<div>Turnover 2019: <span class="badge mx-2 bg-warning">952411.33</span></div>
<div>Turnover 2020: <span class="badge mx-2">6135840.0</span></div>
<div>Total Turnover: 7088251.33</div>
</div>
</html>
Because the year numbers and XML element names are a moving target in your XML, you would have to keep adjusting the XSLT code every year. That's completely unnecessary. It's a lot smarter to keep the year out of the XML element names. Move it into an attribute:
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnover year="2019">952411.33</turnover>
<turnover year="2020">6135840.0</turnover>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
With a <creditcard> setup like this, the XSLT code gets more generic.
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<xsl:apply-templates select="$cc/turnover" />
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="sum($cc/turnover)" />
</div>
</div>
</xsl:template>
<xsl:template match="turnover">
<div>
<xsl:value-of select="concat('Turnover ', #year, ': ')" />
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</div>
</xsl:template>
I'm new in XSLT. I would like to transform xml to html using xslt. I want to add div elements in which will be nested some attributes based on the condition.
I have following xml:
<xml version="1.0" encoding="UTF-8"?>
<ns:form xmlns:ns="http://abcdefghij/datatypes/">
<ns:sectors>
<ns:sector>
<ns:sectorID>Title</ns:sectorID>
<ns:controls>...</ns:controls>
</ns:sector>
<ns:sector>
<ns:sectorID>Image1</ns:sectorID>
<ns:controls>...</ns:controls>
</ns:sector>
<ns:sector>
<ns:sectorID>Content1</ns:sectorID>
<ns:controls>...</ns:controls>
</ns:sector>
<ns:sector>
<ns:sectorID>Links</ns:sectorID>
<ns:controls>...</ns:controls>
</ns:sector>
<ns:sector>
<ns:sectorID>Buttons</ns:sectorID>
<ns:controls>...</ns:controls>
</ns:sector>
</ns:sectors>
</ns:form>
And I would like to get:
<div id="sablona1" class="override-ckeditor">
<div id="Title">...</div>
<div>
<div id="Image1">...</div>
<div id="Content1">...</div>
<div id="Links">...</div>
</div>
<div id="Buttons">...</div>
</div>
I have tried this xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://abcdefghij/datatypes/" xmlns:xls="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="ns">
<xsl:output method="html" />
<xsl:template match="/ns:form">
<div id="sablona1" class="override-ckeditor">
<xsl:for-each select="ns:sectors/ns:sector">
<!-- starts the code, which is not working -->
<xsl:choose>
<xsl:when test="ns:sectorID = 'Image1'">
<div>
</xsl:when>
<xsl:when test="ns:sectorID = 'Buttons'">
</div>
</xsl:when>
</xsl:choose>
<!-- ends the code, which is not working -->
<div>
<xsl:attribute name="id">
<xsl:value-of select="ns:sectorID"/>
</xsl:attribute>
<xsl:apply-templates select="ns:controls"/>
</div>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
But it returns error:
Unable to generate the XML document using the provided XML/XSL input.
org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 23; The
element type "div" must be terminated by the matching end-tag
"</div>".
I probably understand what is wrong, but I have no idea how to fix it.
Please could you give me some advices?
Thanks.
XSLT is not a word processor. It works with a node tree, not individual tags. And an XSLT stylesheet must be a well-formed XML document, too.
Try perhaps a different approach:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://abcdefghij/datatypes/"
exclude-result-prefixes="ns">
<xsl:output method="html"/>
<xsl:template match="/ns:form">
<div id="sablona1" class="override-ckeditor">
<div id="Title">
<xsl:value-of select="ns:sectors/ns:sector[1]/ns:controls"/>
</div>
<div>
<xsl:for-each select="ns:sectors/ns:sector[position() > 1]">
<div id="{ns:sectorID}">
<xsl:value-of select="ns:controls"/>
</div>
</xsl:for-each>
</div>
</div>
</xsl:template>
</xsl:stylesheet>
Or, if you prefer:
<xsl:template match="/ns:form">
<div id="sablona1" class="override-ckeditor">
<div id="Title">
<xsl:value-of select="ns:sectors/ns:sector[ns:sectorID = 'Title']/ns:controls"/>
</div>
<div>
<xsl:for-each select="ns:sectors/ns:sector[ns:sectorID !='Title']">
<div id="{ns:sectorID}">
<xsl:value-of select="ns:controls"/>
</div>
</xsl:for-each>
</div>
</div>
</xsl:template>
I am trying to use the < sub > < /sub > tag to make parts of my xml file subscripts when opened online but there is an issue when I open up the xml file in Internet Explorer (doesn't say what error just does not look right in IE). I think it is because xml is reading < sub > as another child element but < sub > is just supposed to be used to tell hmtl to make certain parts of the xml file subscripts online. Any ideas on what to change? I am also using xsl to convert xml to html for online publication. The code for that is below
XML File:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="ALDformat.xsl"?>
<ALD_data>
<Element Title = "lithium">
<Element>lithium </Element>
<Compound Subtitle = "Li<sub>2</sub>CO<sub>3</sub>">
<Compound> Li<sub>2</sub>CO<sub>3</sub> </Compound>
<Precursor>
<precursor1> Li(thd) </precursor1>
<precursor2> O<sub>3</sub> </precursor2>
<Ref2> Putkonen2009 </Ref2>
</Precursor>
</Compound>
<Compound Subtitle = "Li<sub>2</sub>O(LiOH)">
<Compound> Li<sub>2</sub>O(LiOH) </Compound>
<Precursor>
<precursor1> Li(O<sup>t</sup>Bu) </precursor1>
<precursor2> H<sub>2</sub>O </precursor2>
<Ref2> Aaltonen2010 </Ref2>
</Precursor>
</Compound>
</Element>
</ALD_data>
XSL File:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<h1>ALD literature XML database</h1>
<p>Last update: 6 January 2016</p>
<xsl:for-each select="ALDdata/Element">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"> Element: <xsl:value-of select="Element"/> </span>
</div>
<xsl:for-each select="Compound">
<div style="background-color:lightgrey;margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<span> Compound: <xsl:value-of select="Compound"/> </span>
</p>
</div>
<xsl:for-each select="Precursor">
<div style="margin-left:30px;margin-bottom:1em;font-size:10pt">
<p>
Precursor 1: <xsl:value-of select="precursor1"/> <br/>
Precursor 2: <xsl:value-of select="precursor2"/>
</p>
Post-2005 review paper references
<ol>
<xsl:for-each select="Ref2">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</ol>
</div>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
In order for your sub and sup elements to be processed, you'll have to use xsl:apply-templates instead of xsl:value-of for the elements that contain sub and sup.
I don't think you can use a literal result element as a stylesheet and add templates.
Maybe try something like this instead...
XML Input (Note: I had to remove the values of the Compound/#Subtitle attributes as they are not well-formed.)
<?xml-stylesheet type="text/xsl" href="ALDformat.xsl"?>
<ALD_data>
<Element Title = "lithium">
<Element>lithium </Element>
<Compound Subtitle = "">
<Compound> Li<sub>2</sub>CO<sub>3</sub> </Compound>
<Precursor>
<precursor1> Li(thd) </precursor1>
<precursor2> O<sub>3</sub> </precursor2>
<Ref2> Putkonen2009 </Ref2>
</Precursor>
</Compound>
<Compound Subtitle = "">
<Compound> Li<sub>2</sub>O(LiOH) </Compound>
<Precursor>
<precursor1> Li(O<sup>t</sup>Bu) </precursor1>
<precursor2> H<sub>2</sub>O </precursor2>
<Ref2> Aaltonen2010 </Ref2>
</Precursor>
</Compound>
</Element>
</ALD_data>
XSLT 1.0 (ALDformat.xsl)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<h1>ALD literature XML database</h1>
<p>Last update: 6 January 2016</p>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Element[#Title]">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"> Element: <xsl:apply-templates select="Element"/> </span>
</div>
<xsl:apply-templates select="Compound"/>
</xsl:template>
<xsl:template match="Compound[#Subtitle]">
<div style="background-color:lightgrey;margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<span> Compound: <xsl:apply-templates select="Compound"/> </span>
</p>
</div>
<xsl:apply-templates select="Precursor"/>
</xsl:template>
<xsl:template match="Precursor">
<div style="margin-left:30px;margin-bottom:1em;font-size:10pt">
<p>
Precursor 1: <xsl:apply-templates select="precursor1"/> <br/>
Precursor 2: <xsl:apply-templates select="precursor2"/>
</p>
Post-2005 review paper references
<ol>
<xsl:apply-templates select="Ref2"/>
</ol>
</div>
</xsl:template>
<xsl:template match="sub|sup">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Ref2">
<li><xsl:apply-templates/></li>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<h1>ALD literature XML database</h1>
<p>Last update: 6 January 2016</p>
<div style="background-color:teal;color:white;padding:4px"><span style="font-weight:bold"> Element: lithium </span></div>
<div style="background-color:lightgrey;margin-left:20px;margin-bottom:1em;font-size:10pt">
<p><span> Compound: Li<sub>2</sub>CO<sub>3</sub></span></p>
</div>
<div style="margin-left:30px;margin-bottom:1em;font-size:10pt">
<p>
Precursor 1: Li(thd) <br>
Precursor 2: O<sub>3</sub></p>
Post-2005 review paper references
<ol>
<li> Putkonen2009 </li>
</ol>
</div>
<div style="background-color:lightgrey;margin-left:20px;margin-bottom:1em;font-size:10pt">
<p><span> Compound: Li<sub>2</sub>O(LiOH) </span></p>
</div>
<div style="margin-left:30px;margin-bottom:1em;font-size:10pt">
<p>
Precursor 1: Li(O<sup>t</sup>Bu) <br>
Precursor 2: H<sub>2</sub>O
</p>
Post-2005 review paper references
<ol>
<li> Aaltonen2010 </li>
</ol>
</div>
</body>
</html>
You can't place HTML in a stylesheet right away, your XSLT must have the stylesheet element at the top level, and have template elements as child content, like
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<h1>ALD literature XML database</h1>
<p>Last update: 6 January 2016</p>
<xsl:for-each select="ALDdata/Element">
<!-- ... -->
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I must admit, it's been a while since I used in-browser XSLT. Are you using IE by chance?
Currently the displaying the XML in a browser along with the XSL data is correct except for one thing. In some colleges I have one department while in orders I have more than one (up to 9). How I can dynamically output the data based on the number of department for each college? Currently it only outputs one department per college.
College.xml File
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="colleges.xsl"?><colleges>
<college id="0">
<school>College of Education</school>
<mission>text</mission>
<department id="0">Educational Psychology and Leadership</department>
<department id="1">Health and Human Performance</department>
<department id="2">Language, Literacy and Intercultural Studies</department>
<department id="3">Teaching, Learning and Innovation</department>
</college>
<college id="1">
<school>College of Nursing</school>
<mission>text</mission>
<department id="0">Nursing</department>
</college>
<college id="2">
<school>School of Business</school>
<mission>text</mission>
<department id="0">Accounting and Management Information Systems</department>
<department id="1">Applied Business Technology</department>
</college></colleges>
College.xsl file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="colleges/college">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="school"/></span> - <br /><xsl:value-of select="mission"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:value-of select="department"/><br />
</p>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Try:
<xsl:template match="/"> ...
<xsl:for-each select="colleges/college">
...
<xsl:apply-templates select="department"/>
...
</xsl:for-each>
</xsl:template>
<xsl:template match="department">... what you want for each department</xsl:template>
Give this a shot...
<xsl:template match="/">
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="colleges/college">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="school"/></span> - <br /><xsl:value-of select="mission"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:apply-templates select="department"/>
</p>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="department">
<xsl:value-of select="."/><br />
</xsl:template>