首页 文章

XQuery包含三个独立的XML文件

提问于
浏览
0

在尝试学习XQuery时,我试图编写一个查询,从三个独立的XML文件中选择信息 . 我对XQuery有一点经验,但我只能在每个XML文件中提供信息 .

Person.xml

<AllPersons>
  <Person>
    <Name>Jinchao Henson</Name>
    <ID>118784412</ID>
  </Person>
  <Person>
    <Name>Min Tuyet</Name>
    <ID>201586985</ID>
  </Person>
  <Person>
    <Name>John Basaraba</Name>
    <ID>124208644</ID>
  </Person>
  <Person>
    <Name>Richard Ellison</Name>
    <ID>997111094</ID>
  </Person>
  ...
</AllPersons>

Student.xml

<AllStudents>
  <Student>
    <StudentID>118784412</StudentID>
    <MentorID>201586985</MentorID>
  </Student>
  <Student>
    <StudentID>124208644</StudentID>
    <MentorID>997111094</MentorID>
  </Student>
  ...
</AllStudents>

Faculty.xml
<AllFaculty>
<学部>
<FacultyID> 201586985 </ FacultyID>
<秩>教授</排名>
</学部>
<学部>
<FacultyID> 997111094 </ FacultyID>
<秩>阅读器</排名>
</学部>
...
</ AllFaculty>

家庭作业问题是要求选择每个学生及其导师 . 我试图编写一个循环遍历学生的查询,选择学生节点,然后为Person和Faculty节点添加两个let表达式,然后返回学生的姓名和Faculty的名称,但无法使其工作 . 我还尝试了一个遍历学生的查询,一个让Faculty的表达式,一个where子句,将StudentID与FacultyID匹配,将StudentID与Person / ID匹配,然后返回该Person / Name,然后循环通过匹配ID的教师和返回姓名 .

任何帮助深表感谢 . 谢谢 .

Edit: 感谢您的建议 . 我清理了XML示例,这是一个尝试:

for $student in doc("../Student.xml")//Student
let $faculty := doc("../Faculty.xml")//Faculty
let $person := doc("../Person.xml")//Person
where $student/MentorID = $faculty/FacultyID and $student/StudentID = $person/ID
return
  <StudentMentor>{
      $person/Name,
      <Mentor>{
        for $personTwo in doc("../Person.xml")//Person
          where $personTwo/ID = $faculty/FacultyID
          return $personTwo/Name
      }</Mentor>
    }
 </StudentMentor> 
}

我是XQuery的新手,所以我不知道构造这个查询的最佳方法 .

Edit 2: 在仔细查看数据后,我想我不会尝试更好的(实际工作)解决方案 .

Edit 3: 这是我的工作解决方案,请告知我如何提高效率 .

for $student in doc("../Student.xml")//Student
let $personS := doc("../Person.xml")//Person[ID = $student/StudentID]
for $personM in doc("../Person.xml")//Person[ID = $student/MentorID]
return 
  <StudentMentor>
    <Student>{$personS/Name}</Student>,
    <Mentor>{$personM/Name}</Mentor>
  </StudentMentor>

1 回答

  • 0

    更好的代码可能看起来像这样:

    declare variable $students := doc("../Students.xml")/AllStudents/Student;
    declare variable $faculty := doc("../Faculty.xml")/AllFaculty/Faculty;
    declare variable $persons := doc("../Person.xml")/AllPersons/Person;
    
    for $student in $students
    let $faculty := $faculty[FacultyID=$student/MentorID]
    let $student_person := $persons[ID=$student/StudentID]
    let $faculty_person := $persons[ID=$student/MentorID]
    return
      <StudentMentor>{
          $student_person/Name,
          <Mentor>{$faculty_person/Name}</Mentor>
        }</StudentMentor>
    

    使用上面的测试数据,我得到以下输出:

    <StudentMentor>
      <Name>Jinchao Henson</Name>
      <Mentor>
        <Name>Min Tuyet</Name>
      </Mentor>
    </StudentMentor>
    <StudentMentor>
      <Name>John Basaraba</Name>
      <Mentor>
        <Name>Richard Ellison</Name>
      </Mentor>
    </StudentMentor>
    

    注意:

    • 这里没有任何 where 条款;你的查询不需要它们,选择一大堆可能的排列并使用win下降的位置是非常低效的(或者至少是单一的),而不是直接找到你真正想要的数据 .

    • 没有必要选择"let"内的所有学生,教师或人员;对于整个查询将是全局的任何内容,而不是作用于使用"for"迭代的项目,应该声明为变量 .

    • 如果您的数据库未编入索引以避免该递归,则替代使用 // 进行递归搜索而不是明确地通过根节点更有效 . 你可以使用 $students_doc/*/Student (和其他人一样)使用类似的效果 .

相关问题