具有三个单独 XML 文件的 XQuery
XQuery with three separate XML files
在尝试学习 XQuery 时,我正在尝试编写一个查询,该查询 selects 来自 three 两个单独的 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>
<Faculty>
<FacultyID>201586985</FacultyID>
<Rank>Professor</Rank>
</Faculty>
<Faculty>
<FacultyID>997111094</FacultyID>
<Rank>Reader</Rank>
</Faculty>
...
</AllFaculty>
一个家庭作业问题正在问 select 每个学生和他们的导师。我试图编写一个循环遍历 Students 的查询,selecting Student 节点,然后是 Person 和 Faculty 节点的两个 let 表达式,然后 returning 一个 Student 的名字和一个 Faculty 的名字但是无法让它工作。我还尝试了一个循环遍历 Students 的查询,一个 Faculty 的 let 表达式,一个将 StudentID 与 FacultyID 和 StudentID 与 Person/ID 匹配的 where 子句,然后 return 那 Person/Name 然后遍历匹配 ID 和 returning 名称的教员。
非常感谢任何帮助。谢谢。
编辑: 感谢您的建议。我清理了 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 的新手,所以我不知道构建此查询的最佳方式。
编辑 2: 仔细查看数据后,我想我什至不需要 Faculty.xml 文件,我会尝试做一个更好的(实际工作)解决方案。
编辑 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>
更好的代码可能看起来有点像这样:
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
子句;您的查询不需要它们,并且选择大量可能的排列并使用 where 来筛选是非常低效的(或者至少是非惯用的),而不是直接获取您真正想要的数据。
- 没有必要选择 所有 学生、教师或 "let" 内的人员;任何对整个查询来说都是全局的,而不是限定在 "for" 迭代的项目范围内的任何东西都应该声明为变量。
- 如果您的数据库未编制索引以避免递归,则将
//
的使用替换为递归搜索以显式遍历根节点会更有效。您可以使用 $students_doc/*/Student
(其他人也一样)来达到类似的效果。
在尝试学习 XQuery 时,我正在尝试编写一个查询,该查询 selects 来自 three 两个单独的 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>
<Faculty>
<FacultyID>201586985</FacultyID>
<Rank>Professor</Rank>
</Faculty>
<Faculty>
<FacultyID>997111094</FacultyID>
<Rank>Reader</Rank>
</Faculty>
...
</AllFaculty>
一个家庭作业问题正在问 select 每个学生和他们的导师。我试图编写一个循环遍历 Students 的查询,selecting Student 节点,然后是 Person 和 Faculty 节点的两个 let 表达式,然后 returning 一个 Student 的名字和一个 Faculty 的名字但是无法让它工作。我还尝试了一个循环遍历 Students 的查询,一个 Faculty 的 let 表达式,一个将 StudentID 与 FacultyID 和 StudentID 与 Person/ID 匹配的 where 子句,然后 return 那 Person/Name 然后遍历匹配 ID 和 returning 名称的教员。
非常感谢任何帮助。谢谢。
编辑: 感谢您的建议。我清理了 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 的新手,所以我不知道构建此查询的最佳方式。
编辑 2: 仔细查看数据后,我想我什至不需要 Faculty.xml 文件,我会尝试做一个更好的(实际工作)解决方案。
编辑 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>
更好的代码可能看起来有点像这样:
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
子句;您的查询不需要它们,并且选择大量可能的排列并使用 where 来筛选是非常低效的(或者至少是非惯用的),而不是直接获取您真正想要的数据。 - 没有必要选择 所有 学生、教师或 "let" 内的人员;任何对整个查询来说都是全局的,而不是限定在 "for" 迭代的项目范围内的任何东西都应该声明为变量。
- 如果您的数据库未编制索引以避免递归,则将
//
的使用替换为递归搜索以显式遍历根节点会更有效。您可以使用$students_doc/*/Student
(其他人也一样)来达到类似的效果。