0

変数に割り当てられた合計が機能しない理由を理解しようとしています。また、テーブルの出力では、テーブル全体で最初の要素のみが繰り返されています。このコードで実行しようとしているのは、各学生の学生IDを最初の列に印刷し、そのIDの学生名を2番目の列に印刷してから、3つの評価の学生の合計マークを保持する変数を割り当てることです。 3番目の列に合計マークを印刷し、続いて合計マークに基づいてHD、D、C、P、またはFを割り当てます。たとえば、HDは85以上、Dは75以上ですが、84以下などです。 。

誰かが私がどこで間違っているのか教えてもらえますか?私はまだXML/XSLに慣れていないので、批判は大歓迎です。

grade.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

    <xsl:variable name="StudentAmount" select="count(document('AssessmentItems.xml')/assessmentList/unit/studentList/student)"/>
    <xsl:variable name="totalmark" select="sum(document('AssessmentItems.xml')/assessmentList/unit/*
    [//assessmentList/unit/assessmentItems/assessment/@studId = //assessmentList/unit/studentList/student/@sid])"/>

  <html>
  <body>
    <h2>Grade Report for <xsl:value-of select="assessmentList/unit/@unitId"/> - <xsl:value-of select="assessmentList/unit/unitName"/></h2>
    <p>Number of students in this unit: <xsl:value-of select="$StudentAmount"/></p>

    <table border="1">
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Total Mark</th>
        <th>Grade</th>
      </tr>
      <xsl:for-each select="assessmentList/unit/studentList/student">
      <tr>
        <td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student/@sid"/></td>
        <td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student"/></td>
        <td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/assessmentItems/assessment/mark"/></td>

        <xsl:choose>
        <xsl:when test="$totalmark &gt; 85">
        <td color="blue">HD</td>
        </xsl:when>

        <xsl:when test="$totalmark &gt; 75">
        <td color="black">D</td>
        </xsl:when>

        <xsl:when test="$totalmark &gt; 65">
        <td color="black">C</td>
        </xsl:when>

        <xsl:when test="$totalmark &gt; 50">
        <td color="black">P</td>
        </xsl:when>

        <xsl:otherwise>
        <td color="red">F</td>
        </xsl:otherwise>
        </xsl:choose>

      </tr>
      </xsl:for-each>
    </table>

    </body>
  </html>
</xsl:template>
</xsl:stylesheet>

これはファイルAssessmentItems.xmlです

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="grade.xsl"?>
<assessmentList>
    <unit unitId="3311">
        <unitName>Learn To Read</unitName>
        <studentList>
            <student sid="1001">Lisa Simpson</student>
            <student sid="1002">Barney Rubble</student>
            <student sid="1003">Donald Duck</student>
        </studentList>
        <assessmentItems>
            <assessment name="Assignment 1" weight="20">
                <mark studId="1001">12</mark>
                <mark studId="1002">18</mark>
                <mark studId="1003">9</mark>
            </assessment>
            <assessment name="Assignment 2" weight="25">
                <mark studId="1001">23</mark>
                <mark studId="1002">14</mark>
                <mark studId="1003">12.5</mark>
            </assessment>
            <assessment name="Quiz" weight="15">
                <mark studId="1001">13</mark>
                <mark studId="1002">9</mark>
                <mark studId="1003">6</mark>
            </assessment>
            <assessment name="Final Exam" weight="40">
                <mark studId="1001">38</mark>
                <mark studId="1002">21</mark>
                <mark studId="1003">20.5</mark>
            </assessment>
        </assessmentItems>
    </unit>
</assessmentList>
4

2 に答える 2

0

まず、単一のXMLドキュメントのみを操作しているため、document('AssessmentItems.xml')への定数参照はまったく必要ありません。だから、例えば

<xsl:value-of 
   select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student/@sid"/>

だけで置き換えることができます

<xsl:value-of select="/assessmentList/unit/studentList/student/@sid"/>

これは2番目の問題につながります。上記のxpathは、XMLのドキュメント要素に関連しており、最初に見つかった学生の@sidを返しますが、現在配置されている学生の@sidは返しません。あなたはあなたの場合にこれを簡単に行うことができます

<xsl:value-of select="@sid"/>

もう1つの問題は、XSLTの上部で変数の合計マークを定義することです実際には、現在の学生に固有になるように、 xsl:for-eachのスコープ内で定義する必要があります。

<xsl:variable name="totalmark" select="sum(../../assessmentItems/assessment/mark[@studId = current()/@sid])" />

実際には、ここでキーを使用して結果を調べる方がよい場合があります

<xsl:key name="marks" match="mark" use="@studId" />

そして、学生の総合的な結果を得るために....

 <xsl:variable name="totalmark" select="sum(key('marks', @sid))" />

最後のコメントですが、問題はありませんが、xsl:for-eachではなくxsl:apply-templatesを使用する方がよい場合がよくあります。これにより、過度のインデントが回避され、コードの再利用が向上します。

次のXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="marks" match="mark" use="@studId"/>

   <xsl:template match="/">
      <xsl:variable name="StudentAmount" select="count(/assessmentList/unit/studentList/student)"/>
      <html>
         <body>
            <h2>Grade Report for 
               <xsl:value-of select="assessmentList/unit/@unitId"/>- 
               <xsl:value-of select="assessmentList/unit/unitName"/>
            </h2>
            <p>Number of students in this unit: 
               <xsl:value-of select="$StudentAmount"/></p>
            <table border="1">
               <tr>
                  <th>ID</th>
                  <th>Name</th>
                  <th>Total Mark</th>
                  <th>Grade</th>
               </tr>
               <xsl:apply-templates select="assessmentList/unit/studentList/student"/>
            </table>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="student">
      <xsl:variable name="totalmark" select="sum(key('marks', @sid))"/>
      <tr>
         <td>
            <xsl:value-of select="@sid"/>
         </td>
         <td>
            <xsl:value-of select="."/>
         </td>
         <td>
            <xsl:value-of select="$totalmark"/>
         </td>
         <xsl:choose>
            <xsl:when test="$totalmark &gt; 85">
               <td color="blue">HD</td>
            </xsl:when>
            <xsl:when test="$totalmark &gt; 75">
               <td color="black">D</td>
            </xsl:when>
            <xsl:when test="$totalmark &gt; 65">
               <td color="black">C</td>
            </xsl:when>
            <xsl:when test="$totalmark &gt; 50">
               <td color="black">P</td>
            </xsl:when>
            <xsl:otherwise>
               <td color="red">F</td>
            </xsl:otherwise>
         </xsl:choose>
      </tr>
   </xsl:template>
</xsl:stylesheet>

XMLに適用すると、次のHTMLが出力されます。

<html>
   <body>
      <h2>Grade Report for 3311- Learn To Read</h2>
      <p>Number of students in this unit: 3</p>
      <table border="1">
         <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Total Mark</th>
            <th>Grade</th>
         </tr>
         <tr>
            <td>1001</td>
            <td>Lisa Simpson</td>
            <td>86</td>
            <td color="blue">HD</td>
         </tr>
         <tr>
            <td>1002</td>
            <td>Barney Rubble</td>
            <td>62</td>
            <td color="black">P</td>
         </tr>
         <tr>
            <td>1003</td>
            <td>Donald Duck</td>
            <td>48</td>
            <td color="red">F</td>
         </tr>
      </table>
   </body>
</html>

これは、XML内の1つの単位要素のみを想定していることに注意してください。実際のXMLに複数のユニットがあり、それぞれに個別のテーブルが必要な場合、これは問題ではありません。ユニットIDがxsl:keyの一部であることを確認するだけで、特定の結果を検索できます。特定のユニットの学生。

于 2012-05-10T09:58:22.603 に答える
0

コードを一目見ただけで、述語がわかります

[//assessmentList/unit/assessmentItems/assessment/@studId = //assessmentList/unit/studentList/student/@sid]

ソースドキュメント内のすべての要素に対して同じ値(trueまたはfalse)を持っているため、明らかに間違っています。

それを修正するには、私が時間があるよりも多くの問題の研究が必要です。しかし、あなたは「それがうまくいかない場合は、「//」を最前線に置く」という誤謬の犠牲になっているようです。

于 2012-05-10T11:31:16.650 に答える