Reputation: 3
XSLT Code:
<?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>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd[artist='Bob Dylan']">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
**<xsl:value-of select="sum(catalog/cd[artist='Bob Dylan' and extra[not(contains(tests/test,'CD'))]]/price)"/>**
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XML Code:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<extra>
<tests>
<test>CDEF</test>
</tests>
<tests>
<test>QWER</test>
</tests>
<tests>
<test>UIOP</test>
</tests>
</extra>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Red</title>
<artist>Bob Dylan</artist>
<country>UK</country>
<extra>
<tests>
<test>CDEF</test>
</tests>
<tests>
<test>QWER</test>
</tests>
<tests>
<test>UIOP</test>
</tests>
</extra>
<company>London</company>
<price>7.80</price>
<year>1987</year>
</cd>
<cd>
<title>Unchain my heart</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<extra>
<tests>
<test>ABXY</test>
</tests>
<tests>
<test>QWER</test>
</tests>
<tests>
<test>CDOP</test>
</tests>
</extra>
<company>EMI</company>
<price>8.5</price>
<year>1987</year>
</cd>
</catalog>
In the XSLT, I want to take the sum of all that have artists as Bob Dylan, and I want to make sure that I only retrieve test that don't contain CD in their string.
Based on the result, I am taking 8.5. From what I found, my query ignores values from 2-n. What do I need to do to account for them?
I've tried extra[not(contains(tests/test,'CD'))] not(contains(extra/tests/test))], extra/tests[not(contains(tests,CD))]
I've been grasping at straws, so I'd love to have someone enlighten me. Thanks in advance!
Upvotes: 0
Views: 1879
Reputation: 70638
In your original XSLT you have this in your expression...
extra[not(contains(tests/test,'CD'))]
contains
is a string function, which takes 2 strings as arguments. If you pass it a node, it will convert that to a string first. In this case though, you are passing a node-set. In XSLT 1.0, it will convert only the first node in that to a string which is why it doesn't pick up your last cd
. (In XSLT 1.0, passing in a node-set consisting of more than one node throws an error).
You need to do this, so that contains
is applied as a condition to each test
:
<xsl:value-of select="sum(catalog/cd[artist='Bob Dylan' and extra[not(tests/test[contains(., 'CD')])]]/price)"/>
Or you could slightly simplify it to this...
<xsl:value-of select="sum(catalog/cd[artist='Bob Dylan' and not(extra/tests/test[contains(., 'CD')])]/price)"/>
Upvotes: 1