我试图写一个有两部分的Xquery:
第一部分是Xquery中的一个函数,用于计算每个类元素的学生数。函数的输入应该是一个类元素,输出是接受该类的学生数。
在第二部分,我想要至少有一名学生的课程清单(为了找到每门课程的学生人数,我必须使用第一部分的功能)。
这是输入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
{
count(
for $s in doc('data.xml')//Student
let $T:=$e[CrsCode/text()=$s/CrsTaken/@CrsCode and Semester/text()=$s/CrsTaken/@Semester]
where not(fn:empty($T))
return $s
)
};
<Courses>
{for $co in doc('data.xml')//Course,
$c in doc('data.xml')//Class
where $co/@CrsCode=$c/CrsCode/text() and local:numStudents($c)>1
return <course CrsCode="{$co/@CrsCode}" name="{$co/CrsName/text()}" />}
</Courses>
有什么帮助吗?我在Altova Xml间谍中运行此代码并运行没有任何错误,但没有输出。看来文字的内容是错误的。
答案 0 :(得分:1)
您可能更喜欢将查询从where
子句移动到单独的函数中,但这应该有效:
<Courses>{
for $co in doc('data.xml')//Course
let $code := $co/@CrsCode
for $class in doc('data.xml')//Class[CrsCode = $code]
let $sem := $class/Semester
where exists(doc('data.xml')//Student/CrsTaken[@CrsCode = $code and @Semester = $sem])
return <course CrsCode="{ $co/@CrsCode }" name="{ $co/CrsName }" />
}</Courses>
通常,exists()
应该比计算所有学生都要好,因为XQuery处理器应该在1之后停止计数;但是,除非数据集更大,否则这不会产生太大影响。
此外,关于text()
(和data()
)的说明:通常string()
是您想要的,在许多情况下(如此示例),值会自动强制转换为字符串。有关更多信息,Evan Lenz有一个关于这个主题的非常好的博客: