2

Note 1: This is my first question here. Please be gentle.
Note 2: Yes, this is homework. I hate to ask for help, but I've hit a brick wall. If you don't want to tell me the answer, suggesting where to look for the answer would be equally appreciated. Thank you.

I'm trying to write an XSLT sheet that looks at the genre attribute of each DVD element in the target XML file. It is supposed to return a list with each of the different values listed exactly once with a count of the number of times each value was found.

I think my XPath is wrong. To debug, I've tried using <xsl:value-of select="foo"> statements to try different XPath queries, but I haven't had any luck.

Here's the XSL file (I've tried to strip it to the brass tacks)

<?xml version="1.0" encoding="UTF-8"?>
<!-- BrowseAllExample.xsl -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">    
    <xsl:key name="genres" match="DVD" use="@genre" />    
    <xsl:template match="/">
        <html>
            <head>
                <title>Browse: DVDs by Genre</title>
                <link href="../style/browseByGenre.css" rel="stylesheet" type="text/css"/>
            </head>
            <body>
                <!-- TODO: insert page header here -->
                <h2>Browse by Genre</h2>
                <div>                    
                    <!-- This doesn't seem to select anything
                    I've tried lots of combinations with a test
                    xsl:value-of-select element, but nothing 
                    seems to work as a selector except "*"                    
                    -->
                    <xsl:apply-templates select="/dvdlist/DVD[not(@genre=preceding-sibling/@genre)]"
                        mode="genreList">
                        <xsl:sort select="@genre"/>
                    </xsl:apply-templates>
                </div>
            </body>
        </html>
    </xsl:template>
    <!-- 
    List each genre and count titles in each
    -->
    <xsl:template match="DVD" mode="genreList">
        <a href="#{generate-id()}"><xsl:value-of select="@genre"/></a> (<xsl:value-of
            select="count(key('genres',@genre))"/>) - 
    </xsl:template>
</xsl:stylesheet>

Here's the relevant part of the XML file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- dvdlistExample.xml -->
<?xml-stylesheet type="text/xsl" href="BrowseAllExample.xsl"?>
<dvdlist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://example.com/dvdlist ./schema/dvdlist.xsd"
    xmlns="http://example.com/dvdlist">
    <DVD genre="Comedy" itemnum="ID-20">
        <title>American Wedding</title>
        <year>2003</year>
        <price>18.89</price>
        <talent>
            <director>Jesse Dylan</director>
            <actor>Jason Biggs</actor>
            <actor>Sean William Scott</actor>
            <actor/>
        </talent>
        <ratings mpaa="NR" customer="3"/>
        <pics id="ID-20">
            <thumbnail>Wedding-small.jpg</thumbnail>
            <large>Wedding-big.jpg</large>
        </pics>
    </DVD>
    <DVD genre="Action" itemnum="ID-2">
        <title>Badboys II</title>
        <year>2003</year>
        <price>20.27</price>
        <talent>
            <director>Michael Bay</director>
            <actor>Will Smith</actor>
            <actor>Martin Lawrence</actor>
        </talent>
        <ratings mpaa="R" customer="3"/>
        <pics id="ID-2">
            <thumbnail>Badboys-small.jpg</thumbnail>
            <large>Badboys-big.jpg</large>
        </pics>
    </DVD>
    <!--Other DVD entries removed to save space-->
</dvdlist>
  • Hint: Your XML is bound to a namespace: `xmlns="http://example.com/dvdlist"`. If you want to address those elements in your XSLT/XPath, you will need to declare the namespace and use the prefix in your XPath, or match on `namespace-uri()` in a predicate filter. – Mads Hansen Apr 17 '11 at 19:35
  • Wow, XSLT for homework. I don't remember my homework ever being that interesting! +1 for nicely written question. – andyb Apr 17 '11 at 20:08
  • +1 wish every question would be this well-thought! – rekaszeru Apr 17 '11 at 20:22
  • Yes. **This is a FAQ**. Possible duplicate of [How to 'select' from XML with namespaces with XSLT?](http://stackoverflow.com/questions/284094/how-to-select-from-xml-with-namespaces-with-xslt) –  Apr 17 '11 at 20:48

1 Answers1

1

How to 'select' from XML with namespaces? should help you with what you need.

XML Namespaces are simply a way of enabling uniqueness of XML elements and attributes. If two users/companies/whatevers define a <DVD> element the namespace is the way in which they are kept separate. So you could, for example, process two different <DVD> elements by selecting each one along with the appropriate namespace in which it was defined.

Community
  • 1
  • 1
andyb
  • 43,435
  • 12
  • 121
  • 150
  • This plus Mads Hansen's comment above steered me in the right direction. I didn't realize that I had a namespace issue. It never occurred to me that the XPath in the XSLT couldn't resolve the elements in the target XML due to the namespace, although it seems obvious now. Thanks everyone! – SteveTheRed Apr 18 '11 at 02:40