Home > database >  XSL [Beginner] How to use different entities' attribute in a table
XSL [Beginner] How to use different entities' attribute in a table

Time:03-17

I have never coded before so it would probably be a bad question but I am struggling to design the code I want: Here are some of my data (XML document):

<Exam>
      <id>98</id>
      <ExamName>Mathematics</ExamName>
      <ExamGrade>6</ExamGrade>
    </Exam>
    <Exam>
      <id>99</id>
      <ExamName>Mathematics</ExamName>
      <ExamGrade>6</ExamGrade>
    </Exam>
    <Exam>
      <id>100</id>
      <ExamName>Data Management</ExamName>
      <ExamGrade>6</ExamGrade>
    </Exam>
  </Exams>

  <Schools>
    <School>
      <Ranking>1</Ranking>
      <MinimumRequired>6</MinimumRequired>
      <SchoolName>Hardvard</SchoolName>
    </School>
    <School>
      <Ranking>2</Ranking>
      <MinimumRequired>5.7</MinimumRequired>
      <SchoolName>ETH Zurich</SchoolName>
    </School>
    <School>
      <Ranking>3</Ranking>
      <MinimumRequired>5.5</MinimumRequired>
      <SchoolName>SAS's School</SchoolName>
    </School>
    <School>
      <Ranking>4</Ranking>
      <MinimumRequired>5.2</MinimumRequired>
      <SchoolName>Zhaw</SchoolName>
    </School>
  </Schools>

  <Students>
    <Student>
      <id>1</id>
      <Name>Brion</Name>
      <National>National</National>
      <DataManagementGrade>5.2</DataManagementGrade>
    </Student>
    <Student>
      <id>2</id>
      <Name>Niels</Name>
      <National>National</National>
      <DataManagementGrade>4.4</DataManagementGrade>
    </Student>
    <Student>
      <id>3</id>
      <Name>Lukas</Name>
      <National>International</National>
      <DataManagementGrade>4.3</DataManagementGrade>
    </Student>
    <Student>
      <id>4</id>
      <Name>Adelheid</Name>
      <National>International</National>
      <DataManagementGrade>4.4</DataManagementGrade>
    </Student>

I have 3 entities : Student(100 instances);School(4 instances) and Exam(100 instances)

Here is the code I use in my XSL document:

<table >
  <thead>
    <tr>
      <th scope="col">ID</th>
      <th scope="col">Name</th>
      <th scope="col">National / International</th>
      <th scope="col">Data Management Grade</th>
      <th scope="col">Entrance Exam's subject</th>
      <th scope="col">Exam's Grade</th>

    </tr>
  </thead>

  <tbody>

    <xsl:for-each select="data/Students/Student">

      <tr>

        <td>
          <xsl:value-of select="id"/></td>
        <td>
          <xsl:value-of select="Name"/></td>
        <td>
          <xsl:value-of select="National"/></td>
        <td>
          <xsl:value-of select="DataManagementGrade"/></td>

        <td></td>
        <td></td>

      </tr>

    </xsl:for-each>

  </tbody>
</table>

Here is the result: Result of my XSL and XML document

As you see the last 2 columns are empty (Entrance Exam's subject Exam's Grade from 'Exam' instances), I cannot figure out how to get the data from the entity 'Exam' since I am already using '<xsl:for-each select="data/Students/Student">' when I try to add 'xsl:for-each select' with the Exam instance all my columns get empty or a part of the html document is incomplete.

I tried many things and made research on internet but I did not succeed in finding any solution. 'Exam' and 'Student' share the attribute 'id' I wanted to create a key in order to solve this kind of issue but when I try to create and use a key none of my data appear in the document. Plus, ‘id 1’ of “Exam” must match with the row of ‘id 1’ of “Student” and so on for each instances of these entities.

If someone has a solution to my problem I would be very grateful, thanks

CodePudding user response:

You can use XPath to navigate around. Here is how to look up the <Exam> with the same <id> as the current node's (the <Student>'s) <id>.

<xsl:for-each select="Student">
  <!-- ... -->
  <td><xsl:value-of select="/*/Exams/Exam[id = current()/id]/ExamName" /></td>
  <!-- ... -->
</xsl:for-each>

You can also save it in a variable and re-use it.

<xsl:for-each select="Student">
  <!-- Entrance Exam -->
  <xsl:variable name="exam" select="/*/Exams/Exam[id = current()/id]" />

  <!-- ... -->
  <td><xsl:value-of select="$exam/ExamName" /></td>
  <td><xsl:value-of select="$exam/ExamGrade" /></td>
  <!-- ... -->
</xsl:for-each>

or, you can use an XSL key, defined once at the top-level of your stylesheet:

<xsl:key name="examById" match="Exam" use="id" />

<xsl:for-each select="Student">
  <!-- ... -->
  <td><xsl:value-of select="key('examById', id)/ExamName" /></td>
  <td><xsl:value-of select="key('examById', id)/ExamGrade" /></td>
  <!-- ... -->
</xsl:for-each>
  • Related