XSL:无法打印一次而不是多次打印的值

时间:2014-12-07 20:44:51

标签: xml xslt

所以我有一个我正在研究的课程项目并且我已经达到了某一点,但我需要它在每次遇到学生的名字时显示一个值而不是值。它会扫描文档中的学生姓名,当它找到它时,它们的等级是“1 2 3 4”而不是“4”。

此外,如果有人可以帮助我将它变成下一部分的百分比形式,我们将不胜感激!

XSL:

    <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="total_students"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>Grade Report</title>
            </head>
            <body>

                                <h2>A</h2>
                                Number of students receiving grade:
                <xsl:call-template name="print_grade">
                    <xsl:with-param name="target_grade" select="'A'"/>
                </xsl:call-template>
                                <p>Percentage of students receiving grade:</p>
                <p/>

                                <h2>B</h2>
                                Number of students receiving grade:
                <xsl:call-template name="print_grade">
                    <xsl:with-param name="target_grade" select="'B'"/>
                </xsl:call-template>
                                <p>Percentage of students receiving grade:</p>
                <p/>

                                <h2>C</h2>
                                Number of students receiving grade:
                <xsl:call-template name="print_grade">
                    <xsl:with-param name="target_grade" select="'C'"/>
                </xsl:call-template>
                                <p>Percentage of students receiving grade:</p>
                <p/>
            </body>
        </html>
    </xsl:template>
    <xsl:template name="print_grade">
        <xsl:param name="pos" select="1"/>
        <xsl:param name="num" select="1"/>
        <xsl:param name="target_grade"/>
        <xsl:variable name="student" select="/class/student[grade=$target_grade][$pos]"/>
        <xsl:if test="$student">
            <td>
                <xsl:value-of select="$num"/>
            </td>
            <xsl:call-template name="print_grade">
                <xsl:with-param name="pos" select="$pos + 1"/>
                <xsl:with-param name="num" select="$num + 1"/>
                <xsl:with-param name="target_grade" select="$target_grade"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

XML:

<?xml version="1.0"?>
<?xml-stylesheet href="Project7.xsl" type="text/xsl"?>
<!-- XML Project 7 -->

<class>
<student>
    <first-name>Jane</first-name>
    <last-name>Doe</last-name>
    <grade>A</grade>
</student>
<student>
    <first-name>John</first-name>
    <last-name>Smith</last-name>
    <grade>B</grade>
</student>
<student>
    <first-name>Harry</first-name>
    <last-name>Grandson</last-name>
    <grade>A</grade>
</student>
<student>
    <first-name>Lacy</first-name>
    <last-name>Jones</last-name>
    <grade>B</grade>
</student>
<student>
    <first-name>Ulne</first-name>
    <last-name>Douglas</last-name>
    <grade>C</grade>
</student>
<student>
    <first-name>Ambrose</first-name>
    <last-name>Tyler</last-name>
    <grade>B</grade>
</student>
<student>
    <first-name>Roger</first-name>
    <last-name>Clemens</last-name>
    <grade>A</grade>
</student>
<student>
    <first-name>Monroe</first-name>
    <last-name>Hamburger</last-name>
    <grade>A</grade>
</student>
</class>

2 个答案:

答案 0 :(得分:1)

你真的很接近这一点,你只是错过了一点。如果您在模板上查看您的查询:

<xsl:variable name="student" select="/class/student[grade=$target_grade][$pos]"/>

这将返回一个学生。但是:

<xsl:variable name="students" select="/class/student[grade=$target_grade]"/>

将返回所有学生的nodeSet。

<xsl:value-of select="count($students)"/>

将返回该组中的节点数(即具有该等级的学生数)。

鉴于count(/ class / student)为您提供了所有学生的列表,计算百分比应该非常简单。

答案 1 :(得分:0)

考虑使用密钥按student

查找grade个元素
<xsl:key name="student" match="student" use="grade" />

然后,要计算特定年级的学生人数,您可以这样做

<xsl:value-of select="count(key('student', 'A'))" />

你的百分比计算就是这个

<xsl:value-of select="count(key('student', 'A')) div count(/class/student) * 100" />

但是....

如果你要指定&#34; A&#34;,&#34; B&#34;你在这里有一些重复的编码。和&#34; C&#34;分别。这只是你想要的三个等级吗?如果&#34; D&#34;会发生什么?来了,或者&#34; A *&#34;?

好吧,请阅读一项名为Muenchian Grouping的技术。使用这种技术,您可以得到如此不同的等级:

<xsl:for-each select="student[generate-id() = generate-id(key('student', grade)[1])]">

(严格来说,您正在获得学生成分,其成绩是XML中该特定成绩的第一次出现)

在这个循环中,学生的数量就是这样:

<xsl:value-of select="count(key('student', grade))" />

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"  />
    <xsl:key name="student" match="student" use="grade" />

    <xsl:template match="/class">
      <hmtl>
        <head>
          <title>Grade Report</title>
        </head>
        <xsl:variable name="numberOfStudents" select="count(student)" />
        <xsl:for-each select="student[generate-id() = generate-id(key('student', grade)[1])]">
            <h2><xsl:value-of select="grade" /></h2>
            <p>
                <xsl:text>Number of students receiving grade: </xsl:text>
                <xsl:value-of select="count(key('student', grade))" />
            </p>
            <p>
                <xsl:text>%age of students receiving grade: </xsl:text>
                <xsl:value-of select="count(key('student', grade)) div $numberOfStudents * 100" />
            </p>
        </xsl:for-each>
      </hmtl>
    </xsl:template>
</xsl:stylesheet>

还要注意学生总数是如何变量的,以避免在循环中重复计算。