Use for each in xslt - xslt

Input :
<lq>
<ol class="- topic/ol ">
<li>Text 1
<ol class="- topic/ol ">
<li>Text 2</li>
<li>Text 3</li>
</ol>
</li>
<li>Text 4</li>
<li>Text 5</li>
</ol>
</lq>
Out should be :
<node>
<p type="extract_number_1">Text 1</p>
<p type="extract_number_2">Text 2</p>
<p type="extract_number_2">Text 3</p>
<p type="extract_number_1">Text 4</p>
<p type="extract_number_1">Text 5</p>
</node>
Tried code :
<xsl:template match="lq/ol">
<xsl:for-each select="li">
<p type="extract_number_{position()}">
<xsl:apply-templates/>
</p>
</xsl:for-each>
</xsl:template>
I have mentioned above my Input Output should be and Tried code. Here <p> #type should be <li> position.
As my tried code I am not getting expected output. I am using XSLT 2.0. How can I solve this. Thank you.

If you want the number in the type attribute to show the nesting level then use e.g.
<xsl:template match="lq/ol">
<xsl:apply-templates select=".//li"/>
</xsl:template>
<xsl:template match="lq/ol//li">
<p type="extract_number_{count(ancestor::ol)}">
<xsl:value-of select="text()"/>
</p>
</xsl:template>

Related

XSL: Print divider by checking variables

I'm new to XSL and i want to do something like
var oldvalue= ''
for each
get currentvalue
if (oldvalue != currentvalue)
{
print divider
oldvalue = currentvalue
}
end for
I've tried it with
<xsl:variable name="oldname" select="name" />
<xsl:for-each select="myxpathstring">
<xsl:choose>
<xsl:when test="$newname = $newname">
<xsl:variable name="oldname" select="$newname" />
<div class='divider'>divider stuff </div>
</xsl:when>
<xsl:otherwise>No</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
But that doesn't work because i can't update the 'oldname' variable.
Anyone have a solution ?
The complete XSL (with JSP-parameters because i generate the XSL dynamically)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="counter" select="count(<%= request.getParameter("xpath")%>)" />
<div id='counter' class='ui-state-highlight ui-corner-all'><p><span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-info"></span><xsl:value-of select="$counter"/> schema's gevonden</p></div>
<div class="page_navigation ui-widget-header ui-corner-all"></div>
<ul id='schemeslist' class="content">
<xsl:for-each select="<%= request.getParameter("xpath")%>"><!-- filter on sports //scheme[ (sports/sport ='Fietsen') and (planduration=12 or planduration=16)]-->
<xsl:sort select="name"/>
<!-- ////////////////// -->
<!-- print divider if name is new -->
<!-- ////////////////// -->
<li class='scheme' id='scheme'>
<div class='schemeSports'>
<!-- <xsl:for-each select="sports/sport">
<xsl:value-of select="."/>
</xsl:for-each> -->
<xsl:value-of select="sport"/>
</div>
<xsl:variable name="theid" select="#id" />
<div class='schemeName'><xsl:value-of select="name"/></div>
<div class='planDuration'><xsl:value-of select="planduration"/></div>
<div class='fitnessLevel'><xsl:value-of select="fitnesslevel"/></div>
<div class='order'>
<xsl:if test="price != ''"><xsl:value-of select="price"/>euro</xsl:if>
<button class='more' onClick='showInfo("{$theid}")' id='{$theid}'>MEER</button> <button class='buy' onClick='window.location = "buy.html?ID={$theid}"'>KOOP</button>
</div>
</li>
</xsl:for-each>
</ul>
<div style='clear:both'></div>
<div class="page_navigation ui-widget-header ui-corner-all"></div>
</xsl:template>
</xsl:stylesheet>
and here is a sample of the complete xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<schemes lang='nl-BE'>
<scheme id='5E47B7E9'>
<sport>Fietsen</sport>
<author>Energy Lab</author>
<name>Voorbereiding op de Ronde van Vlaanderen</name>
<planduration>16</planduration>
<fitnesslevel>Beginner</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>12</price>
<description>
<![CDATA[...]]>
</description>
</scheme>
<scheme id='5E47B7E9'>
<sport>Triatlon</sport>
<author>Energy Lab</author>
<name>Voorbereiding op de Ronde van Vlaanderen</name>
<planduration>16</planduration>
<fitnesslevel>Expert</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>12</price>
<description>
<![CDATA[...]]>
</description>
</scheme>
<scheme id='5E47B7E9'>
<sport>Fietsen</sport>
<author>Energy Lab</author>
<name>Voorbereiding op een Triatlon</name>
<planduration>24</planduration>
<fitnesslevel>Beginner</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>48</price>
<description>
<![CDATA[...]]>
</description>
</scheme>
</schemes>
Create a function that returns the new value, taking as parameters the old value and the list of values in myxpathstring.
If I understand your XSLT correct you have to use muenchian grouping. Read this article for a description of how this method works.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<schemes lang='nl-BE'>
<scheme id='5E47B7E9'>
<sport>Fietsen</sport>
<author>Energy Lab</author>
<name>Voorbereiding op de Ronde van Vlaanderen</name>
<planduration>16</planduration>
<fitnesslevel>Beginner</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>12</price>
<description><![CDATA[...]]></description>
</scheme>
<scheme id='5E47B7E9'>
<sport>Triatlon</sport>
<author>Energy Lab</author>
<name>Voorbereiding op de Ronde van Vlaanderen</name>
<planduration>16</planduration>
<fitnesslevel>Expert</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>12</price>
<description><![CDATA[...]]></description>
</scheme>
<scheme id='5E47B7E9'>
<sport>Fietsen</sport>
<author>Energy Lab</author>
<name>Voorbereiding op een Triatlon</name>
<planduration>24</planduration>
<fitnesslevel>Beginner</fitnesslevel>
<frequency>1-3</frequency>
<longtraining></longtraining>
<rollers>Ja</rollers>
<price>48</price>
<description><![CDATA[...]]></description>
</scheme>
</schemes>
XSLT:
I replaced the first jsp-tag with a dot and removed the second because I have no idea what you try to achieve with. I do not recommend dynamic *.xsl. You better put these information in your input.xml and query it with xpath.
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>
<xsl:key name='schemata' match='scheme' use='name'/>
<xsl:template match='scheme'>
<li class='scheme' id='scheme'>
<div class='schemeSports'>
<xsl:value-of select="sport"/>
</div>
<xsl:variable name="theid" select="#id"/>
<div class='schemeName'>
<xsl:value-of select="name"/>
</div>
<div class='planDuration'>
<xsl:value-of select="planduration"/>
</div>
<div class='fitnessLevel'>
<xsl:value-of select="fitnesslevel"/>
</div>
<div class='order'>
<xsl:if test="price != ''">
<xsl:value-of select="price"/>
euro
</xsl:if>
<button class='more' onClick='showInfo("{$theid}")' id='{$theid}'>MEER</button>
<button class='buy' onClick='window.location = "buy.html?ID={$theid}"'>KOOP</button>
</div>
</li>
</xsl:template>
<xsl:template match='/schemes'>
<xsl:variable name="counter" select="count(.)"/> <!-- jsp -->
<div id='counter' class='ui-state-highlight ui-corner-all'>
<p>
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-info"/>
<xsl:value-of select="$counter"/>
<xsl:text> schema's gevonden</xsl:text>
</p>
</div>
<div class="page_navigation ui-widget-header ui-corner-all"/>
<ul id='schemeslist' class="content">
<!-- muenchian grouping -->
<xsl:for-each select='scheme[generate-id() = generate-id(key("schemata", name)[1])]'>
<xsl:sort select='name'/>
<xsl:if test='position() != 1'>
<div class='divider'/>
</xsl:if>
<xsl:apply-templates select='key("schemata", name)'/>
</xsl:for-each>
</ul>
<div style='clear:both'/>
<div class="page_navigation ui-widget-header ui-corner-all"/>
</xsl:template>
</xsl:stylesheet>
Result:
<div id="counter" class="ui-state-highlight ui-corner-all">
<p><span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-info"/>1 schema's gevonden</p>
</div><div class="page_navigation ui-widget-header ui-corner-all"/><ul id="schemeslist" class="content">
<li class="scheme" id="scheme">
<div class="schemeSports">Fietsen</div>
<div class="schemeName">Voorbereiding op de Ronde van Vlaanderen</div>
<div class="planDuration">16</div>
<div class="fitnessLevel">Beginner</div>
<div class="order">12
euro
<button class="more" onClick="showInfo("5E47B7E9")" id="5E47B7E9">MEER</button><button class="buy" onClick="window.location = "buy.html?ID=5E47B7E9"">KOOP</button></div>
</li>
<li class="scheme" id="scheme">
<div class="schemeSports">Triatlon</div>
<div class="schemeName">Voorbereiding op de Ronde van Vlaanderen</div>
<div class="planDuration">16</div>
<div class="fitnessLevel">Expert</div>
<div class="order">12
euro
<button class="more" onClick="showInfo("5E47B7E9")" id="5E47B7E9">MEER</button><button class="buy" onClick="window.location = "buy.html?ID=5E47B7E9"">KOOP</button></div>
</li>
<div class="divider"/>
<li class="scheme" id="scheme">
<div class="schemeSports">Fietsen</div>
<div class="schemeName">Voorbereiding op een Triatlon</div>
<div class="planDuration">24</div>
<div class="fitnessLevel">Beginner</div>
<div class="order">48
euro
<button class="more" onClick="showInfo("5E47B7E9")" id="5E47B7E9">MEER</button><button class="buy" onClick="window.location = "buy.html?ID=5E47B7E9"">KOOP</button></div>
</li>
</ul><div style="clear:both"/><div class="page_navigation ui-widget-header ui-corner-all"/>

XSLT 1.0 Grouping on multiple values on multiple levels

edited in response to comments *
Hello,
I am an XSLT noob and need some help. I am trying to do an filter/group combination with XSLT 1.0 (can't use XSLT 2.0 for this application).
Here is an example of the xml
<entry>
<item>
<name>Widget 2</name>
<rank>2</rank>
<types>
<type>Wood</type>
<type>Fixed</type>
<type>Old</type>
</types>
</item>
<item>
<name>Widget 1</name>
<rank>2</rank>
<types>
<type>Metal</type>
<type>Broken</type>
<type>Old</type>
</types>
</item>
<item>
<name>Widget 3</name>
<rank>1</rank>
<types>
<type>Metal</type>
<type>New</type>
</types>
</item>
</entry>
Now what I want to do is output html where I get a subset of the XML based on <type> and then group on rank. For example, if the user selects all items with the type Metal, the output should be:
<p class="nospace"><font color="#800000">
<b>Rank 1</b></font></p>
<li id="mylist"><b>Widget 3</b></li>
<br\>
<p class="nospace"><font color="#800000">
<b>Rank 2</b></font></p>
<li id="mylist"><b>Widget 1</b></li>
<br\>
of if the user user chooses the type Old the output would be
<p class="nospace"><font color="#800000">
<b>Rank 2</b></font></p>
<li id="mylist"><b>Widget 1</b></li>
<li id="mylist"><b>Widget 2</b></li>
<br\>
I can group using keys on rank along easily enough, but trying to do both is not working. Here is a sample of the xslt I have tried:
<xsl:param name="typeParam"/>
<xsl:key name="byRank" use="rank" match="item"/>
<xsl:for-each select="item[count(.|key('byRank',rank)[1])=1]">
<xsl:sort data-type="number" select="rank"/>
<xsl:for-each select="key('byRank',rank)">
<xsl:sort select="name"/>
<xsl:if test="count(rank)>0">
<p class="nospace"><font color="#800000"><b>Rank<xsl:value-of select="rank"/></b></font></p>
<xsl:for-each select="types[types=$typeParam]">
<li id="mylist"><b><xsl:value-of select="../name"/></b></li>
</xsl:for-each>
<br/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
The result I get from this is I do indeed get the subset of my xml that I want but it also displays all of the various rank values. I want to limit it to just the ranks of the type that is specified in $typeParam.
I have tried moving the for-each statement to earlier in the code as well as modifying the if statement to select for $typeParam but neither works. I have also tried concat-ing my key with rank and type but that doesn't seem to work either (It only works if the type in $typeParam is the first child under types).
Thanks
jeff
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kItemByRank" match="item" use="rank"/>
<xsl:param name="pType" select="'Old'"/>
<xsl:template match="entry">
<xsl:for-each select="item[count(.|key('kItemByRank',rank)[1])=1]">
<xsl:sort select="rank" data-type="number"/>
<xsl:variable name="vGroup" select="key('kItemByRank',rank)[
types/type = $pType
]"/>
<xsl:if test="$vGroup">
<p class="nospace">
<font color="#800000">
<b>
<xsl:value-of select="concat('Rank ',rank)"/>
</b>
</font>
</p>
<xsl:apply-templates select="$vGroup">
<xsl:sort select="name"/>
</xsl:apply-templates>
<br/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="item">
<li id="mylist">
<b>
<xsl:value-of select="name"/>
</b>
</li>
</xsl:template>
</xsl:stylesheet>
Output:
<p class="nospace">
<font color="#800000">
<b>Rank 1</b>
</font>
</p>
<li id="mylist">
<b>Widget 3</b>
</li>
<br />
<p class="nospace">
<font color="#800000">
<b>Rank 2</b>
</font>
</p>
<li id="mylist">
<b>Widget 1</b>
</li>
<br />
And whit pType param set to 'Old', output:
<p class="nospace">
<font color="#800000">
<b>Rank 2</b>
</font>
</p>
<li id="mylist">
<b>Widget 1</b>
</li>
<li id="mylist">
<b>Widget 2</b>
</li>
<br />

How to generate the random selection html using xslt

I am using XSLT and XML to generated my HTML.
I have below XML.
1) destinationTabs.xml
<?xml version="1.0"?>
<list type="Tabs">
<tab id="594978-64" title="Overview" url="/destinations_offers/destinations/asiapacific/india/newdelhi/index.aspx" />
<tab id="597468-64" title="Guide" url="/destinations_offers/destinations/asiapacific/india/newdelhi/guide.aspx" />
<tab id="597348-64" title="Flight Schedule" url="/destinations_offers/destinations/asiapacific/india/newdelhi/flightschedule.aspx" />
<tab id="597238-64" title="Special Offers" url="/destinations_offers/destinations/asiapacific/india/newdelhi/specialOffers.aspx" />
<tab id="597243-64" title="Photos" url="/destinations_offers/destinations/asiapacific/india/newdelhi/photo.aspx" />
</list>
Now I want to generate below HTML using XSLT.
<ul class="tabHead tabs-nav">
<li class="tabLeftEnd"></li>
<li class="tabs-selected" id="tab-1"><span>Overview</span></li>
<li id="tab-2"><span>Guide</span></li>
<li id="tab-3"><span>Flight Schedules</span></li>
<li id="tab-4"><span>Special Offers</span></li>
<li id="tab-5"><span>Photos</span></li>
<li class="tabRightEnd"></li>
</ul>
Please note that these are the tabs which depends on the no of the tab ID in destinationTabs.xml and whenever any user click the desired tab a new page is called and it will selected too.
There is a class "tabs-selected" which is flowing on the selection of each tab.
Please suggest!
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSelectedNo" select="1"/>
<xsl:template match="/*">
<ul class="tabHead tabs-nav">
<li class="tabLeftEnd"></li>
<xsl:apply-templates/>
<li class="tabRightEnd"></li>
</ul>
</xsl:template>
<xsl:template match="tab">
<li id="tab-{position()}">
<xsl:if test="position() = $pSelectedNo">
<xsl:attribute name="class">tabs-selected</xsl:attribute>
</xsl:if>
<span><xsl:value-of select="#title"/></span>
</li>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<list type="Tabs">
<tab id="594978-64" title="Overview"
url="/destinations_offers/destinations/asiapacific/india/newdelhi/index.aspx" />
<tab id="597468-64" title="Guide"
url="/destinations_offers/destinations/asiapacific/india/newdelhi/guide.aspx" />
<tab id="597348-64" title="Flight Schedule"
url="/destinations_offers/destinations/asiapacific/india/newdelhi/flightschedule.aspx" />
<tab id="597238-64" title="Special Offers"
url="/destinations_offers/destinations/asiapacific/india/newdelhi/specialOffers.aspx" />
<tab id="597243-64" title="Photos"
url="/destinations_offers/destinations/asiapacific/india/newdelhi/photo.aspx" />
</list>
produces the wanted, correct result:
<ul class="tabHead tabs-nav">
<li class="tabLeftEnd"></li>
<li id="tab-1" class="tabs-selected"><span>Overview</span></li>
<li id="tab-2"><span>Guide</span></li>
<li id="tab-3"><span>Flight Schedule</span></li>
<li id="tab-4"><span>Special Offers</span></li>
<li id="tab-5"><span>Photos</span></li>
<li class="tabRightEnd"></li>
</ul>
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="list">
<ul class="tabHead tabs-nav">
<li class="tabLeftEnd"></li>
<xsl:apply-templates/>
<li class="tabRightEnd"></li>
</ul>
</xsl:template>
<xsl:template match="tab">
<li id="tab-{position()}">
<a href="{#url}">
<span>
<xsl:value-of select="#title"/>
</span>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
Output:
<ul class="tabHead tabs-nav">
<li class="tabLeftEnd"></li>
<li id="tab-1">
<a href="/destinations_offers/destinations/asiapacific/india/newdelhi/index.aspx">
<span>Overview</span>
</a>
</li>
<li id="tab-2">
<a href="/destinations_offers/destinations/asiapacific/india/newdelhi/guide.aspx">
<span>Guide</span>
</a>
</li>
<li id="tab-3">
<a href="/destinations_offers/destinations/asiapacific/india/newdelhi/flightschedule.aspx">
<span>Flight Schedule</span>
</a>
</li>
<li id="tab-4">
<a href="/destinations_offers/destinations/asiapacific/india/newdelhi/specialOffers.aspx">
<span>Special Offers</span>
</a>
</li>
<li id="tab-5">
<a href="/destinations_offers/destinations/asiapacific/india/newdelhi/photo.aspx">
<span>Photos</span>
</a>
</li>
<li class="tabRightEnd"></li>
</ul>
Note: About #class: You need to pass a parameter to the stylesheet, by javascript or by metadata in the retrived resource.

Merge adjacent sibling nodes with XSLT

I have a question that caused me a terrible headache. Please help me. The input is:
<body>
<p class="section"> section 1 </p>
<p class="code"> some code </p>
<p class="code"> following code </p>
<p class="code"> following code </p>
<p class="section"> section 2 </p>
<p class="code"> other code </p>
<p class="code"> following code </p>
<p class="code"> following code </p>
<p class="section"> section 3 </p>
<p class="code"> still other code </p>
<p class="code"> following </p>
<p class="code"> following </p>
</body>
The output I'd like:
<body>
<p class="section"> section 1 </p>
<pre> some code following code following code </pre>
<p class="section"> section 2 </p>
<pre> other code following code following code </pre>
<p class="section"> section 3 </p>
<pre> still other code following following </pre>
</body>
The problem is to collapse to a <pre> tag all adjacent <p class="code"> tags. Don't find a way to do this using XSLT. Do you think a solution exists?
You don't need to rebuild your XML, take a look here: XSLT Grouping Siblings.
With XSLT 2.0 you can use for-each-group group-adjacent as follows:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="body">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::p[#class = 'code'])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<pre>
<xsl:apply-templates select="current-group()/node()"/>
</pre>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You can use XSLT 2.0 with Saxon 9 or with AltovaXML tools.
Something like this should work:
<xsl:template match="body">
<xsl:apply-templates select="p[#class='section']" />
</xsl:template>
<xsl:template match="p[#class='section']">
<xsl:copy-of select="."/>
<pre>
<xsl:variable name="code" select="following-sibling::p[#class='code']" />
<xsl:for-each select="following-sibling::p">
<xsl:variable name="index" select="position()"/>
<xsl:if test="generate-id(.)=generate-id($code[$index])">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</pre>
</xsl:template>
The issue is that your XML isn't structured enough for a simple XSLT solution.
The different "section"s are not really setup in a way that is easy to extract them. If you have control over the input XML see if you can change it to something like this:
<body>
<p class="section"> section 1
<p class="code"> some code </p>
<p class="code"> following code </p>
<p class="code"> following code </p>
</p>
<p class="section"> section 2
<p class="code"> other code </p>
<p class="code"> following code </p>
<p class="code"> following code </p>
</p>
<p class="section"> section 3
<p class="code"> still other code </p>
<p class="code"> following </p>
<p class="code"> following </p>
</p>
</body>
This will let you define a xsl-template for "section"s in which you can xsl-foreach over the "code" classes.

XSLT: trying to do a contains() with a full XPath. Why does this fail?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="/">
<html>
<body>
<span>
<div style="background-color:#000066;color:#EEEEEE;padding:7px">
<a name="top" style="padding-left:10px;font-size:28pt">Alerting Variables</a>
</div>
</span>
<div style="display:block;padding-left:50px;padding-bottom:10px" class="hbuttons">
LDMS Alerts
LDSM Alerts
Why?
Examples
Resources
</div>
<div style="clear: left;"></div>
<!-- This is the Table of Contents-->
<div style="padding:5px">
<div style="padding:5px;margin-top:10pt;margin-bottom:10pt;font-weight:bold;font-size:20px">Table of Contents -
<a style="position:absolute;margin-left:40px" href="PrintPages/PrintAll.html">
<img border="0" src="images/PrintButton.png" />
</a></div>
<div style="font-family:Arial;font-weight:bold;margin-left:30px;font-size:10pt">
<xsl:if test="contains(identifiers/sectionname/alert/#name, 'Agent Watcher')">
Agent Watcher
<a style="position:absolute;margin-left:40px" href="PrintPages/PrintAW.html">
<img border="0" src="images/PrintButton.png" />
</a>
</xsl:if>
<ol style="margin-top:5">
<xsl:for-each select="identifiers/sectionname/alert">
<xsl:if test="contains(#name, 'Agent Watcher')">
<li style="margin-left:10pt;font-size:8pt">
<a>
<xsl:attribute name="href">#
<xsl:value-of select="#name" /></xsl:attribute>
<xsl:value-of select="#name" />
</a>
</li>
</xsl:if>
</xsl:for-each>
</ol>
</div>
<div style="font-family:Arial;font-weight:bold;margin-left:30px;font-size:10pt">
Intel vPro
<a style="position:absolute;margin-left:40px" href="PrintPages/PrintvPro.html">
<img border="0" src="images/PrintButton.png" />
</a>
<ol style="margin-top:5">
<xsl:for-each select="identifiers/SectionName/alert">
<xsl:if test="contains(#name, 'Intel vPro')">
<li style="margin-left:10pt;font-size:8pt">
<a>
<xsl:attribute name="href">#
<xsl:value-of select="#name" /></xsl:attribute>
<xsl:value-of select="#name" />
</a>
</li>
</xsl:if>
</xsl:for-each>
</ol>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Above is my code sample.
The first xsl:if statement always fails and never shows the Agent Watcher text or print me button. Even if the section is filled out in the XML. If the section is there, the first xsl:if statement fails, but the second one, contained in the xsl:for-each shows the content. How do I get this to work.
I want to have it encompassing so that if the XML has content in the section it will put it up but if not it wont be empty content with a header or vice versa. Attaching sample XML to process.
<identifiers>
<sectionname>
<alert name="Agent Watcher Service Startup"></alert>
<alert name="Agent Watcher Service Not Started"></alert>
<alert name="Agent Watcher Service Uninstalled"></alert>
<alert name="Agent Watcher File Deleted"></alert>
</sectionname>
<sectionname>
<alert name="Intel vPro agentless discovery failure"></alert>
<alert name="Intel vPro System Defense Remediation Alert"></alert>
<alert name="Intel vPro Enhanced System Defense Remediation Alert"></alert>
<alert name="Intel vPro Enhanced System Defense Alert"></alert>
</sectionname>
</identifiers>
Blockquote
I have a few other suggestions but you need to post the entire (relevant) XSLT before I can go on. At least the enclosing template is necessary.
EDIT: Here is my proposal for your stylesheet:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tmp="http://tempuri.org"
exclude-result-prefixes="tmp"
>
<tmp:config>
<tmp:alert label="Agent Watcher" link="PrintPages/PrintAW.html" />
<tmp:alert label="Intel vPro" link="PrintPages/PrintvPro.html" />
</tmp:config>
<xsl:variable name="everyAlert" select="
/identifiers/sectionname/alert
" />
<xsl:template match="/">
<html>
<body>
<!-- 8< snip -->
<div style="...">
<div style="...">
<xsl:text>Table of Contents - </xsl:text>
<a style="..." href="PrintPages/PrintAll.html">
<img border="0" src="images/PrintButton.png" />
</a>
</div>
<xsl:for-each select="document('')/*/tmp:config/tmp:alert">
<xsl:call-template name="section" />
</xsl:for-each>
</div>
</body>
</html>
</xsl:template>
<xsl:template name="section">
<xsl:variable name="this" select="." />
<xsl:variable name="alerts" select="
$everyAlert[contains(#name, $this/#label)]
" />
<xsl:if test="$alerts">
<div style="...">
<a href="#{translate($this/#label, ' ', '_')}">
<xsl:value-of select="$this/#label" />
</a>
<a style="..." href="{$this/#link}">
<img border="0" src="images/PrintButton.png" />
</a>
<ol style="...">
<xsl:for-each select="$alerts">
<li style="...">
<xsl:value-of select="#name" />
</li>
</xsl:for-each>
</ol>
</div>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Key features:
efficient code reuse through a named template
printed sections are easily configurable
uses <xsl:text> elements to avoid unwanted whitespace in the output while retaining freedom to format the XSLT code properly
uses attribute literal notation (the curly braces {}) instead of verbose <xsl:attribute> elements
uses a temporary namespace to allow storing config data in the stylesheet itself
uses an <xsl:for-each> loop and the document() function to retrieve and work with that config data
the for-each makes use of the context to transport the current #label and #link so no <xsl:param> is necessary (the <xsl:template name="section"> runs in tmp:config/tmp:alert context, not in sectionname/alert context!)
uses a global variable ($everyAlert) to store all nodes for later use