Xslt and xpath: match two node attributes
given the following xml:
<student studentID="001">
<dateOfBirth> 1-1-1990 </dateOfBirth>
<name> Ayse Ozer </name>
<sex> F </sex>
<takes> CMPE351 </takes>
<takes> CMPE111 </takes>
<takes> CMPE418 </takes>
</student>
<student studentID="002">
<dateOfBirth> 2-2-1992 </dateOfBirth>
<name> Bircan Korkmaz </name>
<sex> F </sex>
<takes> CMPE418 </takes>
<takes> CMPE111 </takes>
<takes> CMPE352 </takes>
</student>
<course courseCode="CMPE351">
<courseName>
Database systems I
</courseName>
<description>
First course in databases
</description>
</course>
<course courseCode="CMPE111">
<courseName>
Introduction to C
</courseName>
<description>
First course in programming
</description>
</course>
<course courseCode="CMPE352">
<courseName>
Database systems II
</courseName>
<description>
Second course in databases
</description>
</course>
<course courseCode="CMPE418">
<courseName>
Internet Programming
</courseName>
<description>
Programming for the Internet.
</description>
</course>
I need an output like this
Courses made by students:
* Ayse Ozer
o CMPE351 Database systems I
o CMPE111 Introduction to C
* Bircan Korkmaz
o CMPE418 Internet Programming
o CMPE111 Introduction to C
I wrote this xsl code:
<xsl:template match = "school">
<head>
<title>Student</title>
</head>
<body>
<p>Courses Taken By Students:</p>
<xsl:for-each select = "student">
<ul>
<li><xsl:value-of select = "name"/> </li>
<xsl:for-each select = "takes">
<ul>
<li><xsl:value-of select="text()" />
<xsl:value-of select = "../../course[@courseCode=text()]/courseName"/> </li>
</ul>
</xsl:for-each>
</ul>
</xsl:for-each>
</body>
</xsl:template>
<xsl:value-of select = "../../course[@courseCode=text()]/courseName"/>
Problem about above line about text()
+1
Erkan
a source
to share
2 answers
The problem is with the space:
<takes> CMPE351 </takes>
it should be:
<takes>CMPE351</takes>
I'll try to compensate ... an example along the way ... To avoid a lot of problems (and improve performance), I also use the xsl index ...
Fixed (caveat - it won't work with course codes with multiple spaces in the middle of them, but that seems unlikely):
<xsl:variable name="code" select="normalize-space()"/>
<ul>
<li>
<xsl:value-of select="$code"/>
<xsl:value-of select="key('courses',$code)/courseName"/>
</li>
</ul>
with (top) xsl index:
<xsl:key name="courses" match="/school/course" use="@courseCode"/>
+1
a source to share
I worked through this example before you already had a good answer. Since this is just a slightly different approach, I thought I would post it anyway.
<?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" indent="no" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:key name="courses" match="course" use="@courseCode"/>
<xsl:template match="school">
<html>
<body>
<p>Courses taken by:</p>
<ul>
<xsl:apply-templates select="student"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="student">
<li>
<xsl:value-of select="name"/>
<ul>
<xsl:apply-templates select="takes"/>
</ul>
</li>
</xsl:template>
<xsl:template match="takes">
<li>
<xsl:value-of select="."/>
<xsl:value-of select="key('courses', normalize-space(.))/courseName"/>
</li>
</xsl:template>
</xsl:stylesheet>
0
a source to share