如何在xslt中将变量增加1?

时间:2017-10-05 10:07:05

标签: xml 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>

我想得到通过所有科目的学生人数。我怎么做? 我得到了一种方法,我遍历所有学生并展示谁通过了所有学生,但我如何得到所有学生的数量。

我正在使用,

<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>

2 个答案:

答案 0 :(得分:1)

您需要的是对于已通过所有考试的学生的“不同”学生姓名的计数。如果您定义了一个键来查找测试,那可能会有所帮助

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

然后,为了获得通过学生的独特列表,您可以在XSLT 2.0中使用distinct-values

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

试试这个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>

答案 1 :(得分:0)

这样的事可能有效

<?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>

输出

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

首先,它使用来自How to use XSLT to create distinct values的方法构造唯一名称列表 - 然后计算匹配2个条件的节点数 - pass为true且name等于当前唯一名称。如果count等于测试次数(2 - 我将其设置为硬编码) - 名称将添加到输出中。

修改

要计算名称 - 您可以将它们存储到temp var中,然后使用简单计数

<?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>