xQuery 1.0, подсчет элементов

У меня проблема с написанием XQuery. У меня есть этот файл XML:

<?xml version="1.0" encoding="UTF-8"?>
<book>
  <title>Data</title>
  <author>Serge Abiteboul</author>
  <author>Peter Buneman</author>
  <author>Dan Suciu</author>
  <section id="intro" difficulty="easy" >
    <title>Chapter1</title>
    <p>Text ... </p>
    <section>
      <title>SubChapter1</title>
      <p>Text ... </p>
    </section>
    <section>
      <title>SubChapter2</title>
      <p>Text ... </p>
      <figure height="400" width="400">
        <title>Figure1</title>
        <image source="csarch.gif"/>
      </figure>
      <p>Text ... </p>
    </section>
  </section>
  <section id="syntax" difficulty="medium" >
    <title>Chapter2</title>
    <p>Text ... </p>
    <figure height="200" width="500">
      <title>Figure2</title>
      <image source="graphs.gif"/>
    </figure>
    <p>Text ... </p>
    <section>
      <title>SubChapter3</title>
      <p>Text ... </p>
    </section>
    <section>
      <title>SubChapter6</title>
      <p>Text ... </p>
      <figure height="250" width="400">
        <title>Figure3</title>
        <image source="relations.gif"/>
      </figure>
    </section>
    <section>
      <title>SubChapter5</title>
      <p>Text ... </p>
    </section>       
  </section>
</book> 

Я должен написать Xquery, который будет подсчитывать каждый SubChapter в главе и каждую цифру в каждой. Я дошел до этого момента до сих пор:

    for $x in doc("file.xml")/book
    return ((<main>{data($x/title)}</main>),
(<mChapter nrSubChapter="{count($x/section/title)}" nrFigure="{count($x/section/section/figure)}">{***data($x/section/title)***}</mChapter>),
    (<mChapter nrSubChapter="{count($x/section/title}" nrFigures="{count($x//figure)}">{***data($x/section/title)***}</mChapter>))

Также я не знаю, как поставить заголовок главы в местах, отмеченных ***.

1 ответ

Решение

Есть несколько вещей, которые я не понимаю в вашем примере запроса. Прежде всего, for $x in doc(...)/* не будет зацикливаться на нескольких узлах, так как в XML-документе есть один корневой элемент (это ложь, но давайте притворимся, что для простоты нет исключения).

Использование круглых скобок делает запрос довольно трудным для чтения. Почему бы не использовать более естественную структуру XML для вывода?

То, что вы хотите сделать, это извлечь что-то из всей книги (название), затем циклически перебирать разделы, затем для каждого из них перебирать свои собственные (под) разделы.

let $book := doc('file.xml')/book
return
   <result>
      <main>{ xs:string($book/title) }</main>
      {
         for $section in $book/section
         return
            <chapter nrSubChapter="{ count($section/section) }"
                     nrFigure="{ count($section/figure) }">
               <title>{ xs:string($section/title) }</title>
               {
                  for $sub in $section/section
                  return
                     <section nrFigure="{ count($sub/figure) }">
                        <title>{ xs:string($sub/title) }</title>
                     </section>
               }
            </chapter>
      }
   </result>

Если у вас может быть несколько уровней разделов, вам придется использовать рекурсию.

Кроме того, как сказал Дженс, вы не сообщили нам точный формат вывода, который вам нужен, поэтому я просто дам вам идею, как решить эту проблему, вам придется адаптировать его к вашим точным требованиям.

PS: обратите внимание, я не проверял код.

Другие вопросы по тегам