XQuery несколько файлов XML? - PullRequest
       9

XQuery несколько файлов XML?

8 голосов
/ 27 января 2009

Можно ли открыть 2 документа из xQuery и объединить их?

Ответы [ 3 ]

10 голосов
/ 27 января 2009

Да, вот пример из спецификации XQuery .:

"Объединения, которые объединяют данные из нескольких источников в один результат, являются очень важным типом запроса. В этом разделе мы покажем, как несколько типов объединений могут быть выражены в XQuery. Мы будем основывать наши примеры на следующем три документа:

  1. Документ с именем parts.xml, содержащий много элементов part; каждый элемент part в свою очередь содержит partno и description подэлементов.
  2. Документ с именем suppliers.xml, который содержит множество supplier элементов; каждый элемент supplier в свою очередь содержит suppno и suppname подэлементов.
  3. Документ с именем catalog.xml, который содержит информацию об отношениях между поставщиками и деталями. Документ каталога содержит множество item элементов, каждый из которых, в свою очередь, содержит partno, suppno и price подэлементов.

Обычное («внутреннее») объединение возвращает информацию из двух или более связанных источников, как показано в следующем примере, который объединяет информацию из трех документов. В этом примере создается «описательный каталог», полученный из документа каталога, но содержащий описания деталей вместо номеров деталей и имена поставщиков вместо номеров поставщиков. Новый каталог упорядочен в алфавитном порядке по описанию детали, а затем по названию поставщика. *

<descriptive-catalog>
   { 
     for $i in fn:doc("catalog.xml")/items/item,
         $p in fn:doc("parts.xml")/parts/part[partno = $i/partno],
         $s in fn:doc("suppliers.xml")/suppliers
                  /supplier[suppno = $i/suppno]
     order by $p/description, $s/suppname
     return
        <item>
           {
           $p/description,
           $s/suppname,
           $i/price
           }
        </item>
   }
</descriptive-catalog>

Предыдущий запрос возвращает информацию только о деталях, у которых есть поставщики и поставщики, у которых есть детали. внешнее объединение - это объединение, которое сохраняет информацию из одного или нескольких участвующих источников, включая элементы, которые не имеют соответствующего элемента в другом источнике. Например, левое внешнее соединение между поставщиками и деталями может возвращать информацию о поставщиках, у которых нет подходящих деталей. "

Обратите внимание, что XQuery не имеет стандартной функции document () (это XSLT-функция ) и вместо этого имеет doc () функция, которая является частью функций и операторов XQuery 1.0 и XPath 2.0".

В ответе есть как минимум две ошибки Криса :

  1. XQuery чувствителен к регистру - ключевые слова с заглавными буквами, используемые в примере Криса, не будут разрешены соответствующим процессором XQuery.
  2. Нет необходимости ставить префикс стандартных функций , таких как doc (), я просто цитирую спецификацию XQuery, которая имеет префикс. В противном случае в моем собственном коде я бы пропустил префикс "fn".
  3. Функция document () не является стандартной функцией XQuery / XPath . Вместо этого следует использовать функцию doc () .
2 голосов
/ 25 октября 2012

это проще (по крайней мере, с использованием SAXON):

let $items := (
     doc("file1.xml") ,
     doc("file2.xml") ,
     doc("file3.xml")
)

for $x in $items ...
0 голосов
/ 27 января 2009

В XQuery, если вы напишите что-то вроде следующего:

for $x in doc('doc1.xml')//a
for $y in doc('doc2.xml')//a
where $x/@name = $y/@name
return $x

тогда ваш процессор XQuery должен быть достаточно умным, чтобы определить, что это соединение.

Вы никогда явно не указываете в XQuery, что что-то является соединением. Общей темой в XQuery является то, что ваша программа сообщает какую информацию вы хотите, а не как для ее вычисления.

Хотя на практике может показаться, что вы многократно повторяете второй документ, реальный процессор XQuery будет выполнять это более разумно, примерно аналогично следующему выражению SQL (мой SQL очень ржавый, поэтому я извиняюсь, если этот синтаксис полностью неверен )

SELECT doc1.a
FROM doc1 INNER JOIN doc2
WHERE doc1.name = doc2.name

Тест XMark содержит несколько примеров запросов, которые стоит посмотреть. В отдельных запросах с 9 по 12 выполняются объединения.

...