Sorry if my title isn't very clear: it is hard for me to come up with a proper way of phrasing my problem concisely.
Here is what my XML
structure looks like:
<library>
<books>
<book writers="007,911">
<title>Two authors wrote me</title>
<price>4.00</price>
</book>
<book writers="911">
<title>Only one here</title>
<price>2.50</price>
</book>
</books>
<authors>
<author id="007">
<name>James</name>
</author>
<author id="911">
<name>Police</name>
</author>
<author id="666">
<name>Diablo</name>
</author>
</authors>
</library>
My goal, for every author
: to list their children (here I only present name
), but also to list all of the book
s where the current id
matches at least one of the writers
. If no book
-match is found, then the list of book
s for that specific author
shouldn't appear. That list should be sorted in descending order of price for all the matches.
Here is the essential XSLT
parts of code I've done so far:
<xsl:template match="/"> <!-- I'm skipping all the irrelevant <html> stuff, of course. -->
<body>
<ol>
<xsl:for-each select="//author">
<li>
<b>ID: </b><xsl:value-of select="@id"/>
<ul>
<xsl:call-template name="auth_infos"></xsl:call-template>
<xsl:call-template name="books_stuff"></xsl:call-template>
</ul>
</li>
</xsl:for-each>
</ol>
</body>
</xsl:template>
<xsl:template name="auth_infos">
<li><b>Name: </b><xsl:value-of select="name"/></li>
</xsl:template>
<xsl:template name="books_stuff">
<xsl:if test="//book[//author/@id = @writers]"> <!-- This is supposed to make sure that if the author doesn't have any books listed in the database, then there shouldn't be an empty list of books. Only his name should be presented. -->
<li><b>Book(s): </b>
<xsl:for-each select="//book[//author/@id = @writers]">
<xsl:sort select="price" order="descending"/> <!-- Because I would also like to sort them based on their price. -->
<li><b>Title: </b><xsl:value-of select="//title"/></li>
</xsl:for-each>
</li>
</xsl:if>
</xsl:template>
Obviously I'm having trouble with this particular XPath
expression: "//book[//author/@id = @writers]"
. I can't seem to understand how I can make sure that I only verify the match for the id of the current author
being iterated on. Also, since book
s can have multiple writers
(IDREFS
to author
's id), I'm unsure how to apply a contains
operator.
The result would be something like this:
-ID: 007
-Name: James
-Book(s):
-Title: Two authors wrote me
-ID: 911
-Name: Police
-Book(s):
-Title: Two authors wrote me
-Title: Only one here
-ID: 666
-Name: Diablo