D. Storm
D. Storm

Reputation: 3

How to check if string is contained in a list?

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

Answers (1)

Tim C
Tim C

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

Related Questions