I have such XML
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="do.xsl"?>
<catalog>
<cd>
<title_>Empire Burlesque</title_>
<artist>Bobby</artist>
<company>Columbia</company>
</cd>
<cd>
<title_>Shirt2</title_>
<artist>Bobby</artist>
<company>Columbia2</company>
</cd>
<cd>
<title_>Fingers</title_>
<artist>Bobby</artist>
<company>Columbia3</company>
</cd>
<cd>
<title_>Zip1</title_>
<artist>Bobby</artist>
<company>---</company>
</cd>
<cd>
<title_>Zip2</title_>
<artist>Bobby</artist>
<company>---</company>
</cd>
</catalog>
I need to replace — with previous meaningful data – Columbia3
I do next
<?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" version="4.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title_"/></td>
<td><xsl:value-of select="artist"/></td>
<td>
<xsl:variable name="NotStarted" select="preceding-sibling::cd[1]/company" />
<xsl:choose>
<xsl:when test="company != '---'">
<xsl:value-of select="company"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$NotStarted" />
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
As expected i got next html
Title Artist
Empire Burlesque Bobby Columbia
Shirt2 Bobby Columbia2
Fingers Bobby Columbia3
Zip1 Bobby Columbia3
Zip2 Bobby ---
How i can iterate back to get last meaningful string to replace with or any other way? Thanks.
This is can be achieved by changing your NotStarted variable
What this is currently doing is finding the immediately preceding sibling, regardless of content, and the getting its company element. What you need to do is find the first preceding sibling which has a valid company name
It is worth noting, it is usually preferable to avoid the use of xsl:for-each and xsl:choose in XSLT, and try to utilitise the power of template matching. Here is an alternate XSLT which demonstrates this
When applied to your XML sample, the following is output