无法使用 Xquery 评估嵌套操作

问题描述 投票:0回答:1

下面是我的 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 之外,一切都正确。请帮我解决这个问题

xml xquery
1个回答
0
投票

如果除了一小部分之外一切都正常,请尝试减少示例,使其仅处理该部分,这样我们就不必花费太多时间来查找大量工作代码。以这种方式隔离故障部分甚至可以使答案显而易见,

您的代码让我感到奇怪的是,

Expression
元素显然具有涉及嵌套子表达式的递归结构,但您的
calculateExpression
函数似乎不是递归的,这是解释器后面的代码所期望的设计模式。

© www.soinside.com 2019 - 2024. All rights reserved.