Reputation: 3
I would like to translate the following XML file to a HTML page using XSL:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Recursion.xsl"?>
<CompareResults hasChanges="true">
<CompareItem name="Appel" status="Identical">
<Properties>
<Property name="Abstract" model="false" baseline="false" status="Identical"/>
</Properties>
<CompareItem name="Banaan" status="Identical">
<Properties>
<Property name="Abstract" model="false" baseline="false" status="Identical"/>
</Properties>
</CompareItem>
<CompareItem name="Kiwi" status="Identical">
<CompareItem name="Peer" status="Model only">
<Properties>
<Property name="Abstract" model="false" baseline="false" status="Identical"/>
<Property name="Notes" model="PeerName" status="Model only"/>
</Properties>
</CompareItem>
<Properties>
<Property name="Abstract" model="false" baseline="false" status="Identical"/>
</Properties>
</CompareItem>
</CompareItem>
</CompareResults>
The output should contain the elements that have the @status
"Model only" and the whole path towards this element.
So, for this example:
My thought is that I should realize this by looping recursively through the XML, but the problem is that I can't figure out how templates can return a value. So, can anyone tell me if (and how) it is possible to return values or how to construct the XSL to comply to the required output?
This is my current XSL file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="/CompareResults">
<xsl:apply-templates select="CompareItem"/>
</xsl:template>
<!--CompareItem -->
<xsl:template match="CompareItem">
<xsl:value-of select="@name"/>
<!-- Sub elements -->
<xsl:apply-templates select="CompareItem"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 414
Reputation: 29052
Getting the @name
attribute values of all elements that have the @status
attribute with the value "Model only" as an ul
list can be done without recursion.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*" />
<xsl:template match="/">
<html>
<body>
<ul>
<xsl:apply-templates select="//*[@status = 'Model only']" mode="xx" />
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="xx" >
<li><xsl:value-of select="@name" /></li>
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
Result is:
<html>
<body>
<ul>
<li>Peer</li>
<li>Notes</li>
</ul>
</body>
</html>
This does work well in a browser.
Upvotes: 0
Reputation: 117165
If I am guessing (!) correctly, you want to do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="/CompareResults">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="*[@name and descendant-or-self::*/@status='Model only']">
<p>
<xsl:value-of select="@name" />
</p>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
This will output a p
for every element that satisfies both:
name attribute
;status
attribute with the value of "Model only"
.resulting in:
<html>
<body>
<p>Appel</p>
<p>Kiwi</p>
<p>Peer</p>
<p>Notes</p>
</body>
</html>
Upvotes: 1