Home > Software engineering >  XSLT do not display certain data in foreach
XSLT do not display certain data in foreach

Time:12-15

I have a xml file and it will be displayed through foreach loop but I want to modify the foreach loop to not display data which is equal to zero.

xml:

<Student>
 <detail>
  <name>John</name>
  <subjectA>
      <geography>45<geography>
   </subjectA>
   <subjectB>
      <sci>0<sci>
  </subjectB>
 </detail>

 <detail>
  <name>Alex</name>
  <subjectA>
      <geography>50<geography>
   </subjectA>
   <subjectB>
      <sci>60<sci>
  </subjectB>
 </detail>

 <detail>
  <name>Peter</name>
  <subjectA>
      <geography>100<geography>
   </subjectA>
   <subjectB>
      <sci>70<sci>
  </subjectB>
 </detail>
</Student>

showResult.php

<?php
  header('Access-Control-Allow-Origin: *');
  header('Content-type: application/xml');
  $subject= $_GET['subject'];
?>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="all" match="/">
<meta http-equiv="Cache-control" content="no-cache" />

<table> 
 <xsl:for-each select="Student/detail[position() &lt;=  2 ]"> //loop 2 students only
 <!-- Geography table -->
 <?php if($subject == "A" ):?> 
 <xsl:if test="subjectA/geography!= 0"> //do not display 0
  <tr> 
   <th>Student<th>
   <th>Geography<th>
  </tr>

  <tr> 
   <td><xsl:value-of select="name"/><td>
   <td><xsl:value-of select="subjectA/Geography"/><td>
  </tr>
  </xsl:if>

  <?php elseif($subject == "B"  ):?>
  <xsl:if test="subjectB/sci != 0"> //do not display 0
  <!-- Science table -->
  <tr> 
   <th>Student<th>
   <th>Science <th>
  </tr>

  <tr> 
   <td><xsl:value-of select="name"/><td>
   <td><xsl:value-of select="subjectB/sci"/><td>
  </tr>
  </xsl:if>
  <?php endif;?>
 </table>
</xsl:for-each>

Result now:

| Student | geography| //if $subject = A
| --------|--------  |
| John    | 45       |
| Alex    | 50       |

| Student | Science|  //if $subject = B
| --------|--------|  
| Alex    | 60     |

Expected result:

| Student | geography| //if $subject = A
| --------|--------  |
| John    | 45       |
| Alex    | 50       |

| Student | Science| //if $subject = B
| --------|--------| //should get next student detail if
| Alex    | 60     |   previous student get 0 marks
| Peter   | 70     |

My current problem:

1)The table should show the 3rd student's details if the 1st or 2nd student get 0 marks

2)But the foreach loop can only loop 2 student details which mean the for lopp cannot retrieve 3rd student's details.

How can I make the for loop to get the 3rd student details?

CodePudding user response:

I don't know about PHP. Using only XSLT (version 1.0), it is possible to get the required result with:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>

<xsl:template match="Student"> 
    <table> 
        <tr>
            <th>Student</th>
            <th>Geography</th>
        </tr>
        <xsl:for-each select="detail[subjectA/geography!= 0][position() &lt;= 2]"> 
            <tr> 
                <td>
                    <xsl:value-of select="name"/>
                </td>
                <td>
                    <xsl:value-of select="subjectA/geography"/>
                </td>
            </tr>
        </xsl:for-each>
        <tr>
            <th>Student</th>
            <th>Science</th>
        </tr>
        <xsl:for-each select="detail[subjectB/sci!= 0][position() &lt;= 2]"> 
            <tr> 
                <td>
                    <xsl:value-of select="name"/>
                </td>
                <td>
                    <xsl:value-of select="subjectB/sci"/>
                </td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

But maybe a better way would be to use grouping instead of repeating the same code twice.

  • Related