【问题标题】:writing an xquery function编写一个 xquery 函数
【发布时间】:2013-12-05 07:44:47
【问题描述】:

我正在尝试编写一个包含 2 个部分的 Xquery:

  1. 第一部分是 Xquery 中的一个函数,用于计算每个班级元素的学生人数。该函数的输入应该是一个班级元素,输出是参加该课程的学生人数。
  2. 在第二部分,我想要至少有一个学生的课程列表(为了找到每门课程的学生数量,我必须使用第一部分中的函数)。

输入 xml 文件如下所示:在输入文件中,我们有 3 个不同的元素:Student、Class 和 Course,它们相互关联。

<?xml version="1.0" ?>
<Report Date="1999-12-02">
 <Students>
 <Student StudId="s11">
 <Name><First>John</First><Last>Doe</Last></Name>
 <Status>U2</Status>
 <CrsTaken CrsCode="CS308" Semester="F1997"/> 
 <CrsTaken CrsCode="MAT123" Semester="F1997"/> 
 </Student>
 <Student StudId="s66">
 <Name><First>Joe</First><Last>Public</Last></Name>
 <Status>U2</Status> 
 <CrsTaken CrsCode="MAT123" Semester="F1997"/> 
 </Student>
 </Students>
 <Classes>
 <Class>
 <CrsCode>CS308</CrsCode><Semester>F1997</Semester>
 <ClassRoster Members="s11"/>
 </Class>
 <Class>
 <CrsCode>MAT123</CrsCode><Semester>F1997</Semester>
 <ClassRoster Members="s11 s66"/>
 </Class>
</Classes>
 <Courses>
 <Course CrsCode="CS308">
 <CrsName>Software Engineering</CrsName>
 </Course> 
 <Course CrsCode="MAT123">
 <CrsName>ALgebra</CrsName>
 </Course>
 </Courses>
</Report>

这是我完成的代码。我写了一个函数,它有一个元素作为输入,并将返回一个整数作为学生人数。我还尝试为第二部分调用该函数。但是我的查询有问题。

declare function local:numstudents($e as element())as xs:integer
{for $s in doc('test')//Student
 let $T:=$e[CrsCode/text()=$s/CrsTaken/@CrsCode and Semester/text()=$s/CrsTaken/@Semester]
 where not(fn:empty($T))
 return count($s) };

<Courses>
 {for $co in doc('test')//Course,
    $c in doc('test')//Class
   where $co/@CrsCode=$c/CrsCode/text() and local:numstudents($c)>1
 return <course CrsCode="{$co/@CrsCode}" num="{$co/CrsName/text()}" />}
</Courses> 

问题在于返回序列而不是整数的函数部分。这是错误:(Single item expected, (1, 1) found)。我正在使用http://basex.org/products/live-demo/ 来测试我的xquery。有什么帮助吗?如果可能,请更正我的代码而不是编写新代码:)。这应该是一个简单的查询,但我不知道如何解决它:)

【问题讨论】:

    标签: xml xquery


    【解决方案1】:

    问题出在函数中,您为每个学生调用count,而不是全部计数。

    declare function local:numstudents($e as element())as xs:integer
    {
      count(
        for $s in doc('test')//Student
        let $T:=$e[CrsCode/text()=$s/CrsTaken/@CrsCode and Semester/text()=$s/CrsTaken/@Semester]
        where not(fn:empty($T))
        return $s
      )
    };
    

    更多提示:

    • 您应该能够删除大部分text(...) 调用。大多数时候,它们是不必要的,甚至是错误的。对于比较和其他调用,XQuery 会自动获取元素的数据值,否则最好使用data(...)
    • not(fn:empty($T))$T 相同,如果它被评估为布尔值。
    • 更好地与函数调用保持一致并使用fn: 前缀。
    • 很难理解这些非常短的变量名称发生了什么。为什么不使用$course$class$student

    【讨论】:

    • 我正在尝试在 Altova 中运行此命令,但没有输出,我不知道为什么
    • 这是普通的 XQuery 1.0,应该是相当可移植的。 doc(...) 是实现定义的:也许您需要以某种方式更改此调用?
    • 我将输入的 xml 保存为一个文件,并将该文件称为我的文档
    • 有趣的是,它适用于 Basex 在线演示,但不适用于 Altova,你的机器上安装了 Altova 吗?可以试试吗?
    • 很抱歉我没有。尝试在没有其余函数调用的情况下打开文档并确保它有效。如果是这样,请逐个扩展查询片段以查看其中断的位置。无论如何:你说你根本没有得到 any 输出。函数调用应该总是返回一个数字(可能为零)。你确定这个函数已经执行了吗?
    猜你喜欢
    • 2022-10-15
    • 2022-08-17
    • 2016-06-26
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多