Search code examples
xquerypredicates

XQuery expression with predicates


I'm trying to use an expression with a predicate to display the child nodes for each parent node (the exercise looks silly because this is test data: the final solution has to draw in data from other xml files).

A sample of the data is as follows:

<Schools>
<School>
<name>St John's</name>
<AcademicYear year = "2017"></AcademicYear>
<Subject>English</Subject>
<Subject>Geography</Subject>
<Subject>Maths</Subject>
<AcademicYear year = "2016"></AcademicYear>
<Subject>Maths</Subject>
<Subject>Textiles</Subject>
<Subject>English</Subject>
<AcademicYear year = "2015"></AcademicYear>
<Subject>History</Subject>
<Subject>French</Subject>
<Subject>Spanish</Subject>
</School>

<School>
<name>Marsh Academy</name>
<AcademicYear year = "2017"></AcademicYear>
<Subject>Science</Subject>
<Subject>Geography</Subject>
<Subject>Computer science</Subject>
<AcademicYear year = "2016"></AcademicYear>
<Subject>English</Subject>
<Subject>History</Subject>
<Subject>Maths</Subject>
<AcademicYear year = "2015"></AcademicYear>
<Subject>French</Subject>
<Subject>Geography</Subject>
<Subject>Art</Subject>
</School>

</Schools>

The query is below:

<Schools>
{for $School in doc("test.xml")/Schools/School
return
<School>
  <Name>
  {$School/name}
  </Name>
  {for $i in doc("test.xml")/Schools/[School = $School]/AcademicYear
  return
  <AcademicYear>
    {$i/@year}
    <subject><teacher></teacher><scale></scale></subject>
  </AcademicYear>}
   </School>}
</Schools>

The error appears says "node expected, array found" in relation to line 8. I've tried both a for loop, and simply placing an expression inside the academic year tags as follows

{doc("test.xml")/Schools/[School = $School]/AcademicYear/@year}

Sorry - I'm sure it is simple. I'm a beginner!


Solution

  • There is no child node preceding the predicate.

    When selecting the School elements, move it outside of the predicate as the child node selected from the Schools element, and then inside the predicate filter, refer to the current School element with .:

    for $i in doc("test.xml")/Schools/School[. = $School]/AcademicYear
    

    But if you are iterating over the elements from the same document, why not just use the already selected $School:

    for $i in $School/AcademicYear