xml查询不会处理我的数据

时间:2014-03-25 16:30:18

标签: xml xquery

我试图写一个有两部分的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间谍中运行此代码并运行没有任何错误,但没有输出。看来文字的内容是错误的。

1 个答案:

答案 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有一个关于这个主题的非常好的博客:

https://developer.marklogic.com/blog/text-is-a-code-smell