I am trying to generate a 4 column directory, grouped by the 4 disciplines in my department. One XML file contains the entire group. Each element has a department tag. The construction of the directory would be the following:
Group each entry by discipline.
For each group, cycle through each entry. If the Rank equals Supervisor, fill out the supervisor DIV, otherwise keep generating a div for each person in the group.
Once all entries in the group are exhausted, construct the next column for the next group...
Keep going until all groups are exhausted.
I'm new to XSLT and really need help. I can create a key for each group, and cycle through the entries in the group, but I'm not sure how to cycle through the different groups.
My mark up is below.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="group" match="employee" use="dept" />
<xsl:template match="/">
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<xsl:for-each select="key('group', 'Mechanical')">
<xsl:sort select="name" order="ascending"/>
(I need a conditional here to check if rank = supervisor)
<div class="super">
<h1>Supervisor</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
<div>
<p class="name"><xsl:value-of select="name"/></p>
<p class="ID"><xsl:value-of select="id"/></p>
</div>
</xsl:for-each>
</div>
XML Directory
<?xml version="1.0" encoding="ISO-8859-1" ?>
<directory>
<employee>
<dept></dept>
<rank>Manager</rank>
<name>John Doe</name>
<id>1234</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
</directory>
Output would look something like:
HTML should look something like:
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<div class="super">
<h1>Mechanical Supervisor</h1>
<h2>Supervisor Name</h2>
</div>
<div>
<p class="name">Mech employee name</p>
<p class="ID">Mech employee ID</p>
</div><!--end group A-->
<div class="group">
<div class="super">
<h1>CivilSupervisor</h1>
<h2>Supervisor Name</h2>
</div>
<div>
<p class="name">Civil employee name</p>
<p class="ID">Civil employee ID</p>
</div><!--end group B-->
<div class="group">
<div class="super">
<h1>Electrical Supervisor</h1>
<h2>Supervisor Name</h2>
</div>
<div>
<p class="name">Electrical employee name</p>
<p class="ID">Electrical employee ID</p>
</div><!--end group C-->
</div>
This XSLT 1.0 transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kEmpByDeptRank" match="employee"
use="concat(dept,'+', rank)"/>
<xsl:key name="kEmpByDept" match="employee"
use="dept"/>
<xsl:template match="directory">
<div id="directory">
<xsl:apply-templates select=
"key('kEmpByDeptRank', '+Manager')"/>
<xsl:apply-templates select=
"employee[not(rank='Manager')]"/>
</div>
</xsl:template>
<xsl:template match=
"employee[generate-id()
=
generate-id(key('kEmpByDept', dept)[1])
]
">
<div class="group">
<xsl:apply-templates mode="inGroup" select=
"key('kEmpByDeptRank', concat(dept,'+Supervisor'))"/>
<xsl:apply-templates mode="inGroup" select=
"key('kEmpByDept', dept)[not(rank='Supervisor')]"/>
</div>
</xsl:template>
<xsl:template match="employee[rank='Manager']">
<div class="man">
<h1>Manager</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
</xsl:template>
<xsl:template match="employee[rank='Supervisor']"
mode="inGroup">
<div class="super">
<h1>
<xsl:value-of select="concat(dept, ' Supervisor')"/>
</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
</xsl:template>
<xsl:template match="employee" mode="inGroup">
<div>
<p class="name">
<xsl:value-of select="concat(dept, ' ', name)"/>
</p>
<p class="ID">
<xsl:value-of select="concat(dept, ' ', id)"/>
</p>
</div>
</xsl:template>
<xsl:template match="employee"/>
</xsl:stylesheet>
when applied on this XML document (similar to the provided one, but changed the names and Ids to be distinct):
<directory>
<employee>
<dept></dept>
<rank>Manager</rank>
<name>John Doe</name>
<id>1234</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Jim Smith</name>
<id>2315</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>Supervisor</rank>
<name>Ann Smith</name>
<id>4322</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Peter Pan</name>
<id>2316</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Mike Sims</name>
<id>2317</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>Supervisor</rank>
<name>Amy Dull</name>
<id>4323</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Dan Brown</name>
<id>2318</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>John Kerry</name>
<id>2319</id>
</employee>
</directory>
produces the wanted, correct result:
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<div class="super">
<h1>Mechanical Supervisor</h1>
<h2>Jane Doe</h2>
</div>
<div>
<p class="name">Mechanical Joe Doe</p>
<p class="ID">Mechanical 2314</p>
</div>
<div>
<p class="name">Mechanical Jim Smith</p>
<p class="ID">Mechanical 2315</p>
</div>
</div>
<div class="group">
<div class="super">
<h1>Civil Supervisor</h1>
<h2>Ann Smith</h2>
</div>
<div>
<p class="name">Civil Peter Pan</p>
<p class="ID">Civil 2316</p>
</div>
<div>
<p class="name">Civil Mike Sims</p>
<p class="ID">Civil 2317</p>
</div>
</div>
<div class="group">
<div class="super">
<h1>Electrical Supervisor</h1>
<h2>Amy Dull</h2>
</div>
<div>
<p class="name">Electrical Dan Brown</p>
<p class="ID">Electrical 2318</p>
</div>
<div>
<p class="name">Electrical John Kerry</p>
<p class="ID">Electrical 2319</p>
</div>
</div>
</div>
and it displays in the browser as:
Manager
John Doe
Mechanical Supervisor
Jane Doe
Mechanical Joe Doe
Mechanical 2314
Mechanical Jim Smith
Mechanical 2315
Civil Supervisor
Ann Smith
Civil Peter Pan
Civil 2316
Civil Mike Sims
Civil 2317
Electrical Supervisor
Amy Dull
Electrical Dan Brown
Electrical 2318
Electrical John Kerry
Electrical 2319
Explanation: Muenchian method for grouping, and locating an employee (Manager or Supervisor) using a composite key (rank, department).
Related
Consider the following xml document:
<list>
<group name="pilots">
<person nat="france" gender="female">
<name>mark webber</name>
<address>911 somewhere circle, canberra, australia</address>
<team>redbull</team>
</person>
<person nat="poland">
<name>robert kubica</name>
<address>121 zootle road, cape town, south africa</address>
</person>
</group>
<group name="rugby">
<person nat="france">
<name>thomas castaignede</name>
<adresse>30 rue de la paix, mont-de-marsan, france</adresse>
</person>
<person nat="uk">
<name>shane williams</name>
<address>113 best lane, swansea, wales</address>
<team>ospreys</team>
</person>
<person nat=".."> ... </person>
</group>
<group name="..."> .... </group>
</list>
I need to display the list of names of person using a different color in html (red, blue,etc.) for each nationality. I can't figure out how can i achieve at that purpose.
Here is my attempt:
<xsl:template match="list">
<html>
<body>
<xsl:for-each-group select="group/person" group-by="#nat">
<!--<xsl:variable name="color" select="position()"/>-->
<b><xsl:value-of select="current-grouping-key()"/>: </b>
<p> <xsl:value-of select="current-group()/name" separator=", "/></p>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
So you want e.g. <xsl:param name="colours" as="xs:string*" select="'red', 'blue', 'yellow'"/> as a global parameter and CSS <p style="color: {$colours[$index]}"><xsl:value-of select="current-group()/name" separator=", "/></p> where you have bound <xsl:variable name="index" select="position()"/> inside the for-each-group.
I have an xml file, that describes a conversation between Agent and Client. Both parties have a userId, that is assigned in the newParty tag.
Subsequent messages and notices, refer to this userId. I would like for when a message or a notice is processed, that a lookup is done by using the userId, to add the string "Agent" or "Client" to the class property of the generated HTML.
<?xml version="1.0"?>
<chatTranscript startAt="2016-10-06T09:16:40Z" sessionId="0001GaBYC53D000K">
<newParty userId="007957F616780001" timeShift="1" visibility="ALL" eventId="1">
<userInfo personId="" userNick="John Doe" userType="CLIENT" protocolType="FLEX" timeZoneOffset="120"/>
<userData>
<item key="GMSServiceId">5954d184-f89d-4f44-8c0f-a772d458b353</item>
<item key="IdentifyCreateContact">3</item>
<item key="MediaType">chat</item><item key="TimeZone">120</item>
<item key="_data_id">139-e9826bf5-c5a4-40e5-a729-2cbdb4776a43</item>
<item key="firstName">John</item><item key="first_name">John</item>
<item key="lastName">Doe</item>
<item key="last_name">Doe</item>
<item key="location_lat">37.8197</item>
<item key="location_long">-122.4786</item>
<item key="userDisplayName">John Doe</item>
</userData>
</newParty>
<newParty userId="0079581AF56C0025" timeShift="20" visibility="ALL" eventId="2">
<userInfo personId="1" userNick="allendei" userType="AGENT" protocolType="BASIC" timeZoneOffset="120"/>
</newParty>
<message userId="007957F616780001" timeShift="25" visibility="ALL" eventId="3">
<msgText msgType="text" treatAs="NORMAL">This is message one.</msgText>
</message>
<message userId="0079581AF56C0025" timeShift="35" visibility="ALL" eventId="4">
<msgText msgType="text" treatAs="NORMAL">This is message two.</msgText>
</message>
<notice userId="0079581AF56C0025" timeShift="40" visibility="ALL" eventId="5">
<noticeText noticeType="USER_CUSTOM">This is notice one.</noticeText>
</notice>
<notice userId="007957F616780001" timeShift="58" visibility="ALL" eventId="6">
<noticeText noticeType="USER_CUSTOM">This is notice two.</noticeText>
</notice>
<partyLeft userId="007957F616780001" timeShift="90" visibility="ALL" eventId="4" askerId="007957F616780001">
<reason code="3">left due to disconnect</reason>
</partyLeft>
... and my xlt is:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:template match="/chatTranscript">
<html>
<header><xsl:value-of select="#sessionId" /></header>
<xsl:apply-templates select="newParty" />
<xsl:apply-templates select="message/msgText" />
<xsl:apply-templates select="notice/noticeText" />
<xsl:apply-templates select="partyLeft/reason" />
</html>
</xsl:template>
<xsl:template match="newParty[userInfo/#userType='CLIENT']">
<div class="Client" id="{#userId}">
<label>Client: <xsl:value-of select="userInfo/#userNick" /></label>
</div>
</xsl:template>
<xsl:template match="newParty[userInfo/#userType='AGENT']">
<div class="Client" id="{#userId}">
<label>Agent: <xsl:value-of select="userInfo/#userNick" /></label>
</div>
</xsl:template>
<xsl:template match="msgText">
<div class="Messages" id="{../#eventId}">
<label>Message: <xsl:value-of select="text()" /></label>
</div>
</xsl:template>
<xsl:template match="noticeText">
<div class="Notices" id="{../#eventId}">
<label>Notice: <xsl:value-of select="text()" /></label>
</div>
</xsl:template>
<xsl:template match="reason">
<div class="Notices" id="{../#eventId}">
<label>Reason: <xsl:value-of select="text()" /></label>
</div>
</xsl:template>
the desired output is as follows - where the class property(Agent or Client) of Messages and Notices are lookup up via the userID in the newParties at the top.
<html>
<header>0001GaBYC53D000K</header>
<div class="Client" id="007957F616780001"><label>Client: John Doe</label></div>
<div class="Client" id="0079581AF56C0025"><label>Agent: allendei</label></div>
<div class="Messages,Client" id="3"><label>Message: This is message one.</label></div>
<div class="Messages,Agent" id="4"><label>Message: This is message two.</label></div>
<div class="Notices,Agent" id="5"><label>Notice: This is notice one.</label></div>
<div class="Notices,Client" id="6"><label>Notice: This is notice two.</label></div>
<div class="Notices,Client" id="4"><label>Reason: left due to disconnect</label></div>
XSLT has a built-in mechanism for performing lookups. Start by defining a key as:
<xsl:key name="party" match="newParty" use="#userId" />
then use it as shown in the following example:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="party" match="newParty" use="#userId" />
<xsl:template match="/chatTranscript">
<html>
<header>
<xsl:value-of select="#sessionId" />
</header>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="newParty[userInfo/#userType='CLIENT']">
<div class="Client" id="{#userId}">
<label>Client: <xsl:value-of select="userInfo/#userNick" /></label>
</div>
</xsl:template>
<xsl:template match="newParty[userInfo/#userType='AGENT']">
<div class="Client" id="{#userId}">
<label>Agent: <xsl:value-of select="userInfo/#userNick" /></label>
</div>
</xsl:template>
<xsl:template match="message">
<xsl:variable name="party-class">
<xsl:call-template name="lookup-class"/>
</xsl:variable>
<div class="Messages,{$party-class}" id="{#eventId}">
<label>Message: <xsl:value-of select="msgText" /></label>
</div>
</xsl:template>
<xsl:template match="notice">
<xsl:variable name="party-class">
<xsl:call-template name="lookup-class"/>
</xsl:variable>
<div class="Notices,{$party-class}" id="{#eventId}">
<label>Notice: <xsl:value-of select="noticeText" /></label>
</div>
</xsl:template>
<xsl:template match="partyLeft">
<xsl:variable name="party-class">
<xsl:call-template name="lookup-class"/>
</xsl:variable>
<div class="Notices,{$party-class}" id="{#eventId}">
<label>Reason: <xsl:value-of select="reason" /></label>
</div>
</xsl:template>
<xsl:template name="lookup-class">
<xsl:variable name="party-type" select="key('party', #userId)/userInfo/#userType" />
<xsl:choose>
<xsl:when test="$party-type='CLIENT'">Client</xsl:when>
<xsl:when test="$party-type='AGENT'">Agent</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Note that the output is not valid HTML.
I have two XML files which I want to transform into HTML using a single XSL file. In the elements.xml I've got a part which combines values from these XML files by ids. Now in my HTML file, I want to present every <element> as a separate <div> in which I want to list names of effects that are linked in <linkedId>. I assume there would be some extensive use of variables but I can't get my head around it.
For example, output for the first element should look like this:
<div>
<div><p>NAME2</p></div>
<div><p>NAME1</p></div>
</div>
elements.xml
<elements>
<listOfElements>
<element>
<id>ID-element-1</id>
*some data*
</element>
<element>
<id>ID-element-2</id>
*some data*
</element>
(...)
</listOfElements>
<linkedIds>
<linkedId>
<idOfElement>ID-element-1</idOfElement>
<idOfEffect>ID-effect-2</idOfEffect>
<idOfEffect>ID-effect-1</idOfEffect>
<linkedId>
<linkedId>
<idOfElement>ID-element-2</idOfElement>
<idOfEffect>ID-effect-2</idOfEffect>
<idOfEffect>ID-effect-4</idOfEffect>
<idOfEffect>ID-effect-7</idOfEffect>
<linkedId>
(...)
</linkedIds>
</elements>
effects.xml
<effects>
<effect>
<idEffect>ID-effect-1</idEffect>
<name>NAME1</name>
</effect>
<effect>
<idEffect>ID-effect-2</idEffect>
<name>NAME2</name>
</effect>
<effect>
<idEffect>ID-effect-4</idEffect>
<name>NAME4</name>
</effect>
<effect>
<idEffect>ID-effect-7</idEffect>
<name>NAME7</name>
</effect>
</effect>
transform.xsl
<xsl:template match="elements">
<div>
<xsl:for-each select="elements/element">
<xsl:variable name="ElementID" select='linkedIds/linkedId/idOfElement'/>
<xsl:apply-templates select="document('effects.xml')/effects"/>
???
</xsl:for-each>
</div>
</xsl:template>
<xsl:template match="effects">
<xsl:for-each select="effects/effect">
<div>
<p><xsl:value-of select="name"/></p>
</div>
</xsl:for-each>
</xsl:template>
Define two keys
<xsl:key name="k1" match="linkedIds/linkedId" use="idOfElement"/>
<xsl:key name="k2" match="effect" use="idEffect"/>
then in the template matching element use them
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="effects-url" select="'test2016051804.xml'"/>
<xsl:variable name="effects-doc" select="document($effects-url)"/>
<xsl:output method="html" indent="yes"/>
<xsl:key name="k1" match="linkedIds/linkedId" use="idOfElement"/>
<xsl:key name="k2" match="effect" use="idEffect"/>
<xsl:template match="/">
<html lang="en">
<body>
<xsl:apply-templates select="//element"/>
</body>
</html>
</xsl:template>
<xsl:template match="elements/listOfElements/element">
<div>
<xsl:variable name="linkedIds" select="key('k1', id)"/>
<xsl:for-each select="$effects-doc">
<xsl:apply-templates select="key('k2', $linkedIds/idOfEffect)/name"/>
</xsl:for-each>
<!-- with XSLT 2.0 you can simply use
<xsl:apply-templates select="key('k2', key('k1', id), $effects-doc)"/>
for the above 4 lines
-->
</div>
</xsl:template>
<xsl:template match="effect/name">
<div>
<p>
<xsl:value-of select="."/>
</p>
</div>
</xsl:template>
</xsl:stylesheet>
That way the inputs
<elements>
<listOfElements>
<element>
<id>ID-element-1</id> *some data* </element>
<element>
<id>ID-element-2</id> *some data* </element>
</listOfElements>
<linkedIds>
<linkedId>
<idOfElement>ID-element-1</idOfElement>
<idOfEffect>ID-effect-2</idOfEffect>
<idOfEffect>ID-effect-1</idOfEffect>
</linkedId>
<linkedId>
<idOfElement>ID-element-2</idOfElement>
<idOfEffect>ID-effect-2</idOfEffect>
<idOfEffect>ID-effect-4</idOfEffect>
<idOfEffect>ID-effect-7</idOfEffect>
</linkedId>
</linkedIds>
</elements>
and (you can set the parameter effects-url in the stylesheet as needed to your file name)
<effects>
<effect>
<idEffect>ID-effect-1</idEffect>
<name>NAME1</name>
</effect>
<effect>
<idEffect>ID-effect-2</idEffect>
<name>NAME2</name>
</effect>
<effect>
<idEffect>ID-effect-4</idEffect>
<name>NAME4</name>
</effect>
<effect>
<idEffect>ID-effect-7</idEffect>
<name>NAME7</name>
</effect>
</effects>
are transformed into
<html lang="en">
<body>
<div>
<div>
<p>NAME1</p>
</div>
<div>
<p>NAME2</p>
</div>
</div>
<div>
<div>
<p>NAME2</p>
</div>
<div>
<p>NAME4</p>
</div>
<div>
<p>NAME7</p>
</div>
</div>
</body>
</html>
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>
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>