Apologies if the title is bit confusing, had to keep it concise.

Okay so the xml document looks like this

<students>
        <student sid="S2208">
            <fname>Ben</fname>
            <lname>Doe</lname>
            <scourses courseid="DSA" mode="full-time"/>
            <scourses courseid="INT" mode="part-time"/>
        </student>
<students>

<lecturers>
        <lecturer lid="L1101">
            <fname>Dohn</fname>
            <lname>Joe</lname>
            <lcourses courseid="DSA"/>
            <lcourses courseid="INT"/>
            <lcourses courseid="ACT"/>
        </lecturer>
<lecturers>

Using the courseid attribute of scourses in the /students/student is it possible to then retrieve the lid attribute of /lecturers/lecturer by testing whether it exists as an attribute of lcourses? I can only manage to get a 'true' evaluation with the methods I've come up with but not the actual content lid.

Dani AI

Generated

Short summary: you want the lid of the lecturer whose lcourses/@courseid matches the current student scourses/@courseid. was right to ask whether you’re in XSLT — the solution is written inside your xt:scourses loop (so context is the scourses node), and the problem with the ../../../xt:lecturers/xt:lecturer/@lid approach is that it just walks to the lecturers element without testing courseid. Two robust options follow: a variable-based predicate (works in XSLT 1.0) and a key-based lookup (recommended for larger documents). If you have XSLT 2.0 there’s a neat current() shorthand.

XSLT 1.0 (simple, clear):

<!-- inside your xt:for-each select="xt:scourses" -->
<xsl:variable name="cid" select="@courseid"/>
<xsl:value-of select="/xt:lecturers/xt:lecturer[xt:lcourses/@courseid = $cid]/@lid"/>

Notes: place the variable inside the scourses loop so $cid is the current course id. Ensure your xt: prefix in the stylesheet matches the source namespace (or drop the prefix if no namespace).

Better for performance (XSLT 1.0 key):

<!-- top-level in the stylesheet -->
<xsl:key name="lect-by-course" match="xt:lecturer" use="xt:lcourses/@courseid"/>

<!-- inside scourses -->
<xsl:value-of select="key('lect-by-course', @courseid)/@lid"/>

Keys make lookups fast and concise. In XSLT 2.0 you can also write:

<xsl:value-of select="/xt:lecturers/xt:lecturer[xt:lcourses/@courseid = current()/@courseid]/@lid"/>

Final tips: if multiple lecturers can match, decide whether you want the first ([1]) or to join all results; xsl:value-of returns the string value of the first node. Avoid brittle ../../../ paths — use absolute paths or keys. Also confirm your XML has a single root element and that your namespace prefixes align with the stylesheet.

Recommended Answers

All 4 Replies

What are we working with here? XSLT? XPATH? Other?

As retrieving the value may differ slightly as a result

XSLT. Since XSLT uses XPATH to navigate the XML document, how would the result differ?

It wouldn't too much, just where the result came from and how the code was written to select such values.

XPath would return results directly through programming while XSLT creates a whole new XML/TXT/HTML file to which it outputs/reorders information

Okay, here's my xslt transformation to html.

    <xsl:template match="xt:students">
        <h1>Student Schedule</h1>
        <xsl:for-each select="xt:student">
            <p>
                <xsl:value-of select="@sid"/>
                <xsl:text> </xsl:text> 
                <xsl:value-of select="xt:fname"/> 
                <xsl:text> </xsl:text> 
                <xsl:value-of select="xt:lname"/>
            </p>
            <table border="1">
                <tr>
                    <td><b>Course</b></td>
                    <td><b>Lecturer</b></td>
                    <td><b>Time</b></td>
                    <td><b>Venue</b></td>
                </tr>
                <xsl:for-each select="xt:scourses">
                    <tr>
                        <td><xsl:value-of select="@courseid"/> - <xsl:value-of select="@mode"/></td>
                        <td>
                            <xsl:value-of select="../../../xt:lecturers/xt:lecturer/@lid"/>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </xsl:for-each>
    </xsl:template>

It generates a timetable for a particular student. There are going to be different subjects with one lecturer teaching one subject. The problem is, that i can't seem to find away of returning the lecturer id, by matching the attribute courseid of student/scourses to the attribute courseid of lecturer/lcourses.

Is that even possible with XSLT or XPATH?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.