下面是我的 Xquery 代码。重点关注计算表达式
import schema namespace uli = "http://www.cs.man.ac.uk/~sattler/" at "examSchema.xsd";
declare variable $examFile as xs:string external;
declare function local:markAB($answers as element()+, $questions as element()*) as element() {
<result>
<total-mark>{
sum(
for $answer in $answers
let $question := $questions[@id = $answer/@QuestionID]
let $correctValue := local:calculateExpression($question/uli:Expression)
let $answerValue := string($answer/@Value)
let $isCorrect :=
if ($answerValue = "Not Answered") then
false()
else if ($answerValue castable as xs:decimal and $correctValue instance of xs:decimal) then
xs:decimal($answerValue) = $correctValue
else
$answerValue = string($correctValue)
return
if ($isCorrect) then
if (exists($question/@marks)) then xs:decimal($question/@marks) else 1
else
0
)
}</total-mark>
<debug>{
for $answer in $answers
let $question := $questions[@id = $answer/@QuestionID]
let $correctValue := local:calculateExpression($question/uli:Expression)
let $answerValue := string($answer/@Value)
let $isCorrect :=
if ($answerValue = "Not Answered") then
false()
else if ($answerValue castable as xs:decimal and $correctValue instance of xs:decimal) then
xs:decimal($answerValue) = $correctValue
else
$answerValue = string($correctValue)
return
<answer-debug>
<questionID>{$answer/@QuestionID}</questionID>
<answerValue>{$answerValue}</answerValue>
<correctValue>{$correctValue}</correctValue>
<answerType>{
if ($answerValue castable as xs:decimal) then "decimal"
else "string"
}</answerType>
<correctValueType>{
if ($correctValue instance of xs:decimal) then "decimal"
else "string"
}</correctValueType>
<comparisonResult>{
if ($answerValue = "Not Answered") then "Not Answered"
else if ($isCorrect) then "Correct"
else "Incorrect"
}</comparisonResult>
<marks>{
if ($isCorrect) then
if (exists($question/@marks)) then $question/@marks else 1
else
0
}</marks>
</answer-debug>
}</debug>
</result>
};
declare function local:calculateExpression($expression as element()) as xs:decimal {
let $result :=
if ($expression/uli:times) then
fold-left($expression/uli:times/*/@value, 1,
function($acc, $val) { $acc * xs:decimal($val) })
else if ($expression/uli:plus) then
sum(for $num in $expression/uli:plus/*/@value return xs:decimal($num))
else if ($expression/uli:minus) then
if (count($expression/uli:minus/*) = 2) then
xs:decimal($expression/uli:minus[1]/@value) - xs:decimal($expression/uli:minus[2]/@value)
else
0 (: Default value if there aren't exactly two operands :)
else if ($expression/uli:int) then
xs:decimal($expression/uli:int/@value)
else if ($expression/uli:dec) then
xs:decimal($expression/uli:dec/@value)
else
0 (: Default value if no recognized operation is found :)
return
if (empty($result)) then 0 else $result
};
declare function local:answerBookRow($ab as element(uli:AnswerBook), $passP as xs:decimal, $totalMarks as xs:decimal, $questions as element()*) as element()+ {
let $markResult := local:markAB($ab/uli:Answer, $questions)
let $rawMark := $markResult/total-mark
let $percentage := round(($rawMark div $totalMarks) * 100)
let $status := if ($percentage >= $passP) then "Pass" else "Fail"
return
(
<tr>
<td>{$ab/@studentID/string()}</td>
<td>{$rawMark}</td>
<td>{concat($percentage, "%")}</td>
<td>{$status}</td>
</tr>,
<debug>
<studentID>{$ab/@studentID/string()}</studentID>
<rawMark>{$rawMark}</rawMark>
<percentage>{$percentage}</percentage>
<status>{$status}</status>
<answers>{$markResult/debug/*}</answers>
</debug>
)
};
declare function local:examResultsTable($exam, $passP, $totalMarks) {
(
<table>
<tr>
<th>StudentID</th>
<th>Raw Mark</th>
<th>Percentage Mark</th>
<th>Pass/Fail?</th>
</tr>
{
for $AB in $exam//uli:AnswerBook
return local:answerBookRow($AB, $passP, $totalMarks, $exam/uli:Questions/uli:Question)[1]
}
</table>,
<debug>
{
for $AB in $exam//uli:AnswerBook
return local:answerBookRow($AB, $passP, $totalMarks, $exam/uli:Questions/uli:Question)[2]
}
</debug>
)
};
declare function local:examResults($exam) {
let $totalMarks := sum($exam/uli:Questions/uli:Question/@marks)
let $passP := xs:decimal($exam/@PercentageToPass)
return
<results>
<p>
The total number of marks achievable is {$totalMarks} and you need
{$passP}% of these to pass the exam.
{local:examResultsTable($exam, $passP, $totalMarks)[1]}
</p>
{local:examResultsTable($exam, $passP, $totalMarks)[2]}
</results>
};
declare function local:examReport($exam) {
let $results := local:examResults($exam)
return
<html>
<head>
<title>Exam Report</title>
</head>
<body>
<h1>Exam for {$exam/@CourseCode/string()} for the year {$exam/@Year/string()}</h1>
<h2>Exam results</h2>
{$results/*[not(self::debug)]}
<h2>Debug Information</h2>
{$results/debug}
</body>
</html>
};
let $exam := (validate {doc($examFile)})/element(uli:Exam)
return local:examReport($exam)
xml文件是
<?xml version="1.0" encoding="UTF-8"?>
<Exam CourseCode="Math101" Year="2022" PercentageToPass="50"
xmlns="http://www.cs.man.ac.uk/~sattler/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.cs.man.ac.uk/~sattler/ examSchema.xsd">
<AnswerBooks>
<AnswerBook studentID="S12344">
<Answer QuestionID="Q1" Value="Not Answered"/>
<Answer QuestionID="Q2" Value="Not Answered"/>
<Answer QuestionID="Q3" Value="Not Answered"/>
<Answer QuestionID="Q4" Value="Not Answered"/>
<Answer QuestionID="Q5" Value="Not Answered"/>
<Answer QuestionID="Q6" Value="Not Answered"/>
</AnswerBook>
<AnswerBook studentID="S12345">
<Answer QuestionID="Q1" Value="1000"/>
<Answer QuestionID="Q2" Value="100"/>
<Answer QuestionID="Q3" Value="5"/>
<Answer QuestionID="Q4" Value="2"/>
<Answer QuestionID="Q5" Value="Not Answered"/>
<Answer QuestionID="Q6" Value="Not Answered"/>
</AnswerBook>
<AnswerBook studentID="s12346">
<Answer QuestionID="Q1" Value="Not Answered"/>
<Answer QuestionID="Q4" Value="2"/>
<Answer QuestionID="Q2" Value="7.5"/>
<Answer QuestionID="Q3" Value="7"/>
<Answer QuestionID="Q5" Value="Not Answered"/>
<Answer QuestionID="Q6" Value="Not Answered"/>
</AnswerBook>
<AnswerBook studentID="s12348">
<Answer QuestionID="Q1" Value="32"/>
<Answer QuestionID="Q2" Value="7.5"/>
<Answer QuestionID="Q3" Value="19"/>
<Answer QuestionID="Q4" Value="2"/>
<Answer QuestionID="Q5" Value="1"/>
<Answer QuestionID="Q6" Value="16"/>
</AnswerBook>
<AnswerBook studentID="S12347">
<Answer QuestionID="Q1" Value="32"/>
<Answer QuestionID="Q2" Value="7"/>
<Answer QuestionID="Q3" Value="19"/>
<Answer QuestionID="Q4" Value="2"/>
<Answer QuestionID="Q5" Value="1"/>
<Answer QuestionID="Q6" Value="15"/>
</AnswerBook>
</AnswerBooks>
<Questions>
<Question id="Q1" marks="3" level="3">
<Expression>
<description/>
<times>
<int value="2"/>
<int value="2"/>
<int value="2"/>
<int value="2"/>
<int value="2"/>
</times>
</Expression>
<Feedback answerCorrect="t">This was a really difficult question because it was very
long: well done!</Feedback>
<Feedback answerCorrect="f">This was a really difficult question because it was very
long - check your working again</Feedback>
</Question>
<Question id="Q2" marks="2" level="3">
<Expression>
<description/>
<times>
<dec value="2.5"/>
<dec value="3"/>
</times>
</Expression>
<Feedback answerCorrect="t">This was a really difficult question: well done!</Feedback>
<Feedback answerCorrect="f">This was a really difficult question - check your working
again and your understanding of decimal numbers.</Feedback>
</Question>
<Question id="Q3" level="2" marks="2">
<Expression>
<description/>
<plus>
<int value="4"/>
<int value="3"/>
<times>
<int value="4"/>
<int value="3"/>
</times>
</plus>
</Expression>
<Feedback answerCorrect="t">Well done!</Feedback>
<Feedback answerCorrect="f">Check your working again and your understanding of
nesting.</Feedback>
</Question>
<Question id="Q4" level="1">
<Expression>
<description/>
<plus>
<int value="1"/>
<int value="1"/>
</plus>
</Expression>
<Feedback answerCorrect="t">Well done!</Feedback>
<Feedback answerCorrect="f">Please pay more attention next time.</Feedback>
</Question>
<Question id="Q5" level="1">
<Expression>
<description/>
<int value="1"/>
</Expression>
<Feedback answerCorrect="t">Well done!</Feedback>
<Feedback answerCorrect="f">Please pay more attention next time.</Feedback>
</Question>
<Question id="Q6" level="2" marks="4">
<Expression>
<description/>
<minus>
<plus>
<int value="2"/>
<int value="3"/>
<times>
<int value="5"/>
<minus>
<int value="6"/>
<int value="3"/>
</minus>
</times>
</plus>
<int value="4"/>
</minus>
</Expression>
<Feedback answerCorrect="t">Well done!</Feedback>
<Feedback answerCorrect="f">Please pay more attention next time.</Feedback>
</Question>
</Questions>
</Exam>
我的任务是检查答案并判断它们是否正确。 除了 Q6 之外,我计算一切都很好。我做错了什么?
下面是我的输出 HTML
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Exam Report</title>
</head>
<body>
<h1>Exam for Math101 for the year 2022</h1>
<h2>Exam results</h2>
<p>
The total number of marks achievable is 13 and you need
50% of these to pass the exam.
<table>
<tr>
<th>StudentID</th>
<th>Raw Mark</th>
<th>Percentage Mark</th>
<th>Pass/Fail?</th>
</tr>
<tr>
<td>S12344</td>
<td>
<total-mark>0</total-mark>
</td>
<td>0%</td>
<td>Fail</td>
</tr>
<tr>
<td>S12345</td>
<td>
<total-mark>1</total-mark>
</td>
<td>8%</td>
<td>Fail</td>
</tr>
<tr>
<td>s12346</td>
<td>
<total-mark>5</total-mark>
</td>
<td>38%</td>
<td>Fail</td>
</tr>
<tr>
<td>s12348</td>
<td>
<total-mark>7</total-mark>
</td>
<td>54%</td>
<td>Pass</td>
</tr>
<tr>
<td>S12347</td>
<td>
<total-mark>5</total-mark>
</td>
<td>38%</td>
<td>Fail</td>
</tr>
</table>
</p>
<h2>Debug Information</h2>
<debug>
<debug>
<studentID>S12344</studentID>
<rawMark>
<total-mark>0</total-mark>
</rawMark>
<percentage>0</percentage>
<status>Fail</status>
<answers>
<answer-debug>
<questionID QuestionID="Q1"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>32</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q2"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>7.5</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q3"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>7</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q4"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>2</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q5"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>1</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q6"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>0</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
</answers>
</debug>
<debug>
<studentID>S12345</studentID>
<rawMark>
<total-mark>1</total-mark>
</rawMark>
<percentage>8</percentage>
<status>Fail</status>
<answers>
<answer-debug>
<questionID QuestionID="Q1"></questionID>
<answerValue>1000</answerValue>
<correctValue>32</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Incorrect</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q2"></questionID>
<answerValue>100</answerValue>
<correctValue>7.5</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Incorrect</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q3"></questionID>
<answerValue>5</answerValue>
<correctValue>7</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Incorrect</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q4"></questionID>
<answerValue>2</answerValue>
<correctValue>2</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="1"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q5"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>1</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q6"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>0</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
</answers>
</debug>
<debug>
<studentID>s12346</studentID>
<rawMark>
<total-mark>5</total-mark>
</rawMark>
<percentage>38</percentage>
<status>Fail</status>
<answers>
<answer-debug>
<questionID QuestionID="Q1"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>32</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q4"></questionID>
<answerValue>2</answerValue>
<correctValue>2</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="1"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q2"></questionID>
<answerValue>7.5</answerValue>
<correctValue>7.5</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="2"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q3"></questionID>
<answerValue>7</answerValue>
<correctValue>7</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="2"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q5"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>1</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q6"></questionID>
<answerValue>Not Answered</answerValue>
<correctValue>0</correctValue>
<answerType>string</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Not Answered</comparisonResult>
<marks>0</marks>
</answer-debug>
</answers>
</debug>
<debug>
<studentID>s12348</studentID>
<rawMark>
<total-mark>7</total-mark>
</rawMark>
<percentage>54</percentage>
<status>Pass</status>
<answers>
<answer-debug>
<questionID QuestionID="Q1"></questionID>
<answerValue>32</answerValue>
<correctValue>32</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="3"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q2"></questionID>
<answerValue>7.5</answerValue>
<correctValue>7.5</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="2"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q3"></questionID>
<answerValue>19</answerValue>
<correctValue>7</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Incorrect</comparisonResult>
<marks>0</marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q4"></questionID>
<answerValue>2</answerValue>
<correctValue>2</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="1"></marks>
</answer-debug>
<answer-debug>
<questionID QuestionID="Q5"></questionID>
<answerValue>1</answerValue>
<correctValue>1</correctValue>
<answerType>decimal</answerType>
<correctValueType>decimal</correctValueType>
<comparisonResult>Correct</comparisonResult>
<marks marks="1"></marks>
</answer-debug>
我期待它评估答案并检查它们是否正确。除了问题 6 之外,一切都正确。请帮我解决这个问题
如果除了一小部分之外一切都正常,请尝试减少示例,使其仅处理该部分,这样我们就不必花费太多时间来查找大量工作代码。以这种方式隔离故障部分甚至可以使答案显而易见,
您的代码让我感到奇怪的是,
Expression
元素显然具有涉及嵌套子表达式的递归结构,但您的 calculateExpression
函数似乎不是递归的,这是解释器后面的代码所期望的设计模式。