2017-10-05 13 views
0

Considérons un cas que je dois obtenir le nombre d'étudiants passés, il est considéré comme réussi s'il passe tous les examens.Comment incrémenter une variable de 1 en xslt?

<testResults version="1.2"> 
<student test="1" pass="true" name="A"></student> 
<student test="2" pass="true" name="A"></student> 
<student test="1" pass="false" name="B"></student> 
<student test="2" pass="true" name="B"></student> 
<student test="1" pass="false" name="C"></student> 
<student test="2" pass="false" name="C"></student> 
<student test="1" pass="true" name="D"></student> 
<student test="2" pass="true" name="D"></student> 
</testResults> 

Je veux connaître le nombre d'étudiants ayant réussi tous les sujets. Comment je fais ça? J'ai eu une méthode où je passe en revue tous les élèves et montre qui a réussi tout mais comment puis-je obtenir le compte de tous les élèves.

J'utilise,

<xsl:for-each select="/testResults/student/[not(@name = preceding::*/@name)]"> 
<xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::pass='false'][@tn = current()/@name])" /> 
<xsl:choose> 
<xsl:when test="$allFailureCount &gt; 0"></xsl:when> 
<xsl:otherwise><xsl:value-of select="@name" /></xsl:otherwise> 
</xsl:choose> 
</xsl:for-each> 
+0

Pouvez-vous éditer votre question pour montrer votre méthode actuelle qui obtient les étudiants qui ont réussi? Merci –

+0

La réponse simple est que vous n'avez pas. En XSLT vous ne pouvez pas changer la valeur d'une variable, vous pouvez la définir une fois et c'est tout. (Oui, je sais que cela semble bizarre au début.) Si vous voulez compter quelque chose, vous appelez la fonction XPath 'count()'. – biziclop

+0

Hey @biziclop Comment utiliseriez-vous la fonction XPath count dans ce cas? –

Répondre

1

Qu'est-ce que vous avez besoin est un compte ici de la « distincte » des noms des étudiants, pour les étudiants qui ont passé tous leurs examens. Il serait sans doute utile si vous avez défini une clé pour rechercher les essais

<xsl:key name="students" match="student" use="@name" /> 

Ensuite, pour obtenir la liste distincte des étudiants qui passent, vous pouvez utiliser distinct-values dans XSLT 2,0

distinct-values(testResults/student[not(key('students', @name)/@pass='false')]/@name) 

Essayez cette XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="text" /> 

    <xsl:key name="students" match="student" use="@name" /> 

    <xsl:template match="/"> 
     <xsl:variable name="passedStudents" select="distinct-values(testResults/student[not(key('students', @name)/@pass='false')]/@name)" /> 

     <xsl:for-each select="$passedStudents"> 
      <xsl:text>Student </xsl:text><xsl:value-of select="." /><xsl:text>&#10;</xsl:text> 
     </xsl:for-each> 
     <xsl:text>Total </xsl:text> 
     <xsl:value-of select="count($passedStudents)" /> 
    </xsl:template> 
</xsl:stylesheet> 
0

Quelque chose comme cela peut fonctionner

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:template match="/"> 
     <result> 
     <xsl:variable name="prods" select="testResults/student/name" /> 
     <xsl:for-each select="$prods"> 
      <xsl:if test="generate-id() = generate-id($prods[. = current()][1])"> 
       <xsl:if test="count(/testResults/student[@pass ='true' and name=current()]) = 2"> 
        <name> 
        <xsl:value-of select="." /> 
        </name> 
       </xsl:if> 
      </xsl:if> 
     </xsl:for-each> 
     </result> 
    </xsl:template> 
</xsl:stylesheet> 

Sortie

<result> 
    <name>A</name> 
    <name>D</name> 
</result> 

D'abord, il construit la liste des noms uniques à l'aide de l'approche How to use XSLT to create distinct values - puis compte le nombre de nœuds correspondant à 2 conditions - pass est true et le nom est égal à un nom de l'ique. Si count est égal au nombre de tests (2 - je le mets en dur) - le nom est ajouté à la sortie.

EDIT

Pour compter les noms - vous pouvez les stocker dans temp var puis utilisez simple comptage

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:template match="/"> 
     <xsl:variable name="prods" select="testResults/student/name" /> 
     <xsl:variable name="passOne"> 
     <xsl:for-each select="$prods"> 
      <xsl:if test="generate-id() = generate-id($prods[. = current()][1])"> 
       <xsl:if test="count(/testResults/student[@pass ='true' and name=current()]) = 2"> 
        <name> 
        <xsl:value-of select="." /> 
        </name> 
       </xsl:if> 
      </xsl:if> 
     </xsl:for-each> 
     </xsl:variable> 
     <xsl:value-of select="count($passOne/name)" /> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Merci, @ artemy-vysotsky Je voulais vraiment le décompte de ceux trouvés, j'ai une approche similaire à la vôtre! mais, la question était d'incrémenter une valeur variable afin que je puisse les compter. Toute autre méthode pour obtenir le compte est également bien. –

+1

Possibilité supplémentaire de compter les noms trouvés –