XQuery - Краткое руководство

Что такое XQuery

XQuery - это функциональный язык, который используется для получения информации, хранящейся в формате XML. XQuery можно использовать в XML-документах, реляционных базах данных, содержащих данные в форматах XML, или базах данных XML. XQuery 3.0 - это рекомендация W3C от 8 апреля 2014 года.

Определение XQuery, данное в его официальной документации, выглядит следующим образом:

XQuery - это стандартизированный язык для объединения документов, баз данных, веб-страниц и почти всего остального. Это очень широко применяется. Это мощный и легкий в освоении. XQuery заменяет проприетарные языки промежуточного программного обеспечения и языки разработки веб-приложений. XQuery заменяет сложные программы Java или C ++ несколькими строками кода. С XQuery проще работать и легче поддерживать, чем со многими другими альтернативами.

Характеристики

  • Functional Language - XQuery - это язык для получения / запроса данных на основе XML.

  • Analogous to SQL - XQuery для XML - это то же самое, что SQL для баз данных.

  • XPath based - XQuery использует выражения XPath для навигации по XML-документам.

  • Universally accepted - XQuery поддерживается всеми основными базами данных.

  • W3C Standard - XQuery - это стандарт W3C.

Преимущества XQuery

  • Используя XQuery, можно получать как иерархические, так и табличные данные.

  • XQuery можно использовать для запроса древовидных и графических структур.

  • XQuery можно напрямую использовать для запроса веб-страниц.

  • XQuery можно напрямую использовать для создания веб-страниц.

  • XQuery можно использовать для преобразования XML-документов.

  • XQuery идеально подходит для баз данных на основе XML и объектных баз данных. Объектные базы данных намного более гибкие и мощные, чем чисто табличные базы данных.

В этой главе описывается, как настроить библиотеку XQuery в локальной среде разработки.

Мы используем автономный процессор XQuery с открытым исходным кодом Saxon Home Edition (Saxon-HE), который широко используется. Этот процессор поддерживает XSLT 2.0, XQuery 3.0 и XPath 3.0 и оптимизирован для повышения производительности. Процессор Saxon XQuery можно использовать без какой-либо базы данных XML. В качестве базы данных в примерах мы будем использовать простой XML-документ.

Чтобы использовать процессор Saxon XQuery, в пути к классам вашего приложения должны быть saxon9he.jar, saxon9-test.jar, saxon9-unpack, saxon9-xqj.jar. Эти файлы jar доступны в файле загрузкиSaxonHE9-6-0-1J.zipЗагрузите SaxonHE9-6-0-1J.zip .

пример

Мы будем использовать основанный на Java процессор Saxon XQuery для проверки books.xqy, файла, содержащего выражение XQuery, на примере нашего XML-документа, т. Е. Books.xml.

В этом примере мы увидим, как написать и обработать запрос для получения элементов заголовка книг, цена которых превышает 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

books.xqy

for $x in doc("books.xml")/books/book where $x/price>30
return $x/title

XQueryTester.java

package com.tutorialspoint.xquery;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;

import com.saxonica.xqj.SaxonXQDataSource;

public class XQueryTester {
   public static void main(String[] args){
      try {
         execute();
      }
      
      catch (FileNotFoundException e) {
         e.printStackTrace();
      }
      
      catch (XQException e) {
         e.printStackTrace();
      }
   }

   private static void execute() throws FileNotFoundException, XQException{
      InputStream inputStream = new FileInputStream(new File("books.xqy"));
      XQDataSource ds = new SaxonXQDataSource();
      XQConnection conn = ds.getConnection();
      XQPreparedExpression exp = conn.prepareExpression(inputStream);
      XQResultSequence result = exp.executeQuery();
      
      while (result.next()) {
         System.out.println(result.getItemAsString(null));
      }
   }	
}

Шаги по выполнению XQuery с XML

  • Step 1 - Скопируйте XQueryTester.java в любое место, например, E: > java

  • Step 2 - Скопируйте books.xml в то же место, E: > java

  • Step 3 - Скопируйте books.xqy в то же место, E: > java

  • Step 4- Скомпилируйте XQueryTester.java с помощью консоли. Убедитесь, что на вашем компьютере установлен JDK 1.5 или новее и пути к классам настроены. Подробнее о том, как использовать JAVA, см. В нашем учебном пособии по JAVA.

E:\java\javac XQueryTester.java
  • Step 5 - Запустить XQueryTester

E:\java\java XQueryTester

Вывод

Вы получите следующий результат -

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Пример понимания

  • books.xml представляет собой образец данных.

  • books.xqy представляет собой выражение XQuery, которое должно выполняться в books.xml. Мы разберемся с выражением более подробно в следующей главе.

  • XQueryTester, программа-исполнитель XQuery на основе Java, считывает файл books.xqy, передает его процессору выражений XQuery и выполняет выражение. Затем результат распечатывается.

пример

Ниже приведен образец XML-документа, содержащего записи книжного магазина различных книг.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

Ниже приведен образец документа Xquery, содержащего выражение запроса, которое должно быть выполнено в указанном выше документе XML. Цель состоит в том, чтобы получить элементы заголовка тех XML-узлов, у которых цена больше 30.

books.xqy

for $x in doc("books.xml")/books/book
where $x/price>30 return $x/title

Результат

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.

Выражения XQuery

Давайте разберемся с каждой частью приведенного выше выражения XQuery.

Использование функций

doc("books.xml")

doc () - одна из функций XQuery, которая используется для поиска источника XML. Здесь мы прошли "books.xml". Учитывая относительный путь, файл books.xml должен находиться по тому же пути, что и файл books.xqy.

Использование выражений XPath

doc("books.xml")/books/book

XQuery активно использует выражения XPath для поиска необходимой части XML, по которой должен производиться поиск. Здесь мы выбрали все узлы книг, доступные в узле книги.

Итерировать объекты

for $x in doc("books.xml")/books/book

XQuery обрабатывает XML-данные как объекты. В приведенном выше примере $ x представляет выбранный узел, а цикл for выполняет итерацию по коллекции узлов.

Применить условие

where $x/price>30

Поскольку $ x представляет выбранный узел, "/" используется для получения значения требуемого элемента; Предложение "where" используется для определения условия для результатов поиска.

Вернуть результат

return $x/title

Поскольку $ x представляет выбранный узел, "/" используется для получения значения требуемого элемента, цены, заголовка; Предложение "return" используется для возврата элементов из результатов поиска.

FLWOR - это аббревиатура от «For, Let, Where, Order by, Return». В следующем списке показано, что они учитывают в выражении FLWOR.

  • F - For - выбирает набор всех узлов.

  • L - Let - помещает результат в переменную XQuery.

  • W - Где - выбирает узлы, указанные в условии.

  • O - Сортировать по - упорядочивает узлы, указанные в соответствии с критериями.

  • R - Return - возвращает окончательный результат.

пример

Ниже приводится образец XML-документа, который содержит информацию о коллекции книг. Мы будем использовать выражение FLWOR для получения названий тех книг, цена которых превышает 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

Следующий документ Xquery содержит выражение запроса, которое должно быть выполнено в указанном выше XML-документе.

books.xqy

let $books := (doc("books.xml")/books/book) return <results> { for $x in $books where $x/price>30
   order by $x/price return $x/title
}
</results>

Результат

<title lang="en">Learn XQuery in 24 hours</title>
<title lang="en">Learn .Net in 24 hours</title>

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.

XQuery также можно легко использовать для преобразования XML-документа в HTML-страницу. Взгляните на следующий пример, чтобы понять, как это делает XQuery.

пример

Мы будем использовать тот же файл books.xml. В следующем примере XQuery извлекает данные из books.xml и создает HTML-таблицу, содержащую названия всех книг с соответствующими ценами.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

Ниже приведено выражение Xquery, которое должно выполняться в вышеуказанном XML-документе.

books.xqy

let $books := (doc("books.xml")/books/book) return <table><tr><th>Title</th><th>Price</th></tr> { for $x in $books order by $x/price
   return <tr><td>{data($x/title)}</td><td>{data($x/price)}</td></tr>
}
</table>
</results>

Результат

<table>
   <tr>
      <th>Title</th>
      <th>Price</th>
   </tr>
   <tr>
      <td>Learn XPath in 24 hours</td>
      <td>16.50</td>
   </tr>   
   <tr>
      <td>Learn Java in 24 Hours</td>
      <td>30.00</td>
   </tr>
   <tr>
      <td>Learn XQuery in 24 hours</td>
      <td>50.00</td>
   </tr>   
   <tr>
      <td>Learn .Net in 24 hours</td>
      <td>70.50</td>
   </tr>
</table>

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.

Выражения XQuery

Здесь мы использовали следующие выражения XQuery -

  • data () для оценки значения элемента заголовка и

  • {}, чтобы указать процессору XQuery рассматривать data () как функцию. Если оператор {} не используется, data () будет рассматриваться как обычный текст.

XQuery совместим с XPath. Он использует выражения XPath для ограничения результатов поиска в коллекциях XML. Дополнительные сведения о том, как использовать XPath, см. В нашем руководстве по XPath .

Вспомните следующее выражение XPath, которое мы использовали ранее для получения списка книг.

doc("books.xml")/books/book

Примеры XPath

Мы воспользуемся файлом books.xml и применим к нему XQuery.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

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

XQuery - Версия 1

(: read the entire xml document :)
let $books := doc("books.xml") for $x in $books/books/book where $x/price > 30
return $x/title

Вывод

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery - Версия 2

(: read all books :)
let $books := doc("books.xml")/books/book

for $x in $books
where $x/price > 30 return $x/title

Вывод

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery - Версия 3

(: read books with price > 30 :)
let $books := doc("books.xml")/books/book[price > 30] for $x in $books return $x/title

Вывод

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.

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

Создание последовательности

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

Выражение XQuery

let $items := ('orange', <apple/>, <fruit type="juicy"/>, <vehicle type="car">sentro</vehicle>, 1,2,3,'a','b',"abc") let $count := count($items) return <result> <count>{$count}</count>
   
   <items>
      {
	     for $item in $items
         return <item>{$item}</item>
      }
   </items>
   
</result>

Вывод

<result>
   <count>10</count>
   <items>
      <item>orange</item>
      <item>
         <apple/>
      </item>
      <item>
         <fruit type="juicy"/>
      </item>
      <item>
         <vehicle type="car">Sentro</vehicle>
      </item>
      <item>1</item>
      <item>2</item>
      <item>3</item>
      <item>a</item>
      <item>b</item>
      <item>abc</item>
   </items>
</result>

Просмотр элементов последовательности

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

Выражение XQuery (индекс)

let $items := (1,2,3,4,5,6)
let $count := count($items)
return
   <result>
      <count>{$count}</count> <items> { for $item in $items[2] return <item>{$item}</item>
      }
      </items>
      
   </result>

Вывод

<result>
   <count>6</count>
   <items>
      <item>2</item>
   </items>
</result>

Выражение XQuery (значение)

let $items := (1,2,3,4,5,6) let $count := count($items) return <result> <count>{$count}</count>
      
      <items>
      {
         for $item in $items[. = (1,2,3)]
         return <item>{$item}</item>
      }
      </items>
      
   </result>

Вывод

<result>
   <count>6</count>
   <items>
      <item>1</item>
      <item>2</item>
      <item>3</item>
   </items>
</result>

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

Старший Нет Имя и описание
1

count ($ seq как элемент () *)

Подсчитывает элементы в последовательности.

2

сумма ($ seq как элемент () *)

Возвращает сумму элементов в последовательности.

3

avg ($ seq как элемент () *)

Возвращает среднее значение элементов в последовательности.

4

min ($ seq как элемент () *)

Возвращает элемент с минимальной стоимостью в последовательности.

5

max ($ seq как элемент () *)

Возвращает элемент с максимальной ценой в последовательности.

6

отдельные значения ($ seq как элемент () *)

Возвращает отдельные элементы из последовательности.

7

подпоследовательность ($ seq как элемент () *, $startingLoc as xs:double, $длина как xs: double)

Возвращает подмножество предоставленной последовательности.

8

вставить перед ($seq as item()*, $позиция как xs: integer, $ вставляет как item () *)

Вставляет элемент в последовательность.

9

remove ($ seq as item () *, $ position as xs: integer)

Удаляет элемент из последовательности.

10

обратный ($ seq как элемент () *)

Возвращает обратную последовательность.

11

индекс чего-либо($seq as anyAtomicType()*, $цель как anyAtomicType ())

Возвращает индексы в виде целых чисел, чтобы указать доступность элемента в последовательности.

12

последний()

Возвращает последний элемент последовательности при использовании в выражении предиката.

13

должность()

Используется в выражениях FLOWR для получения позиции элемента в последовательности.

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

Старший Нет Имя и описание
1

длина строки ($ строка как xs: строка) как xs: целое число

Возвращает длину строки.

2

concat ($ input как xs: anyAtomicType?) как xs: string

Возвращает объединенную строку в качестве вывода.

3

строка-соединение ($sequence as xs:string*, $разделитель как xs: string) как xs: string

Возвращает комбинацию элементов в последовательности, разделенных разделителем.

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

Старший Нет Имя и описание
1

текущая дата()

Возвращает текущую дату.

2

Текущее время()

Возвращает текущее время.

3

current-dateTime ()

Возвращает текущую дату и текущее время.

Ниже приведен список часто используемых функций регулярных выражений, предоставляемых XQuery.

Старший Нет Имя и описание
1

Матчи($input, $регулярное выражение)

Возвращает истину, если входные данные совпадают с предоставленным регулярным выражением.

2

заменить ($input, $регулярное выражение, $ строка)

Заменяет совпадающую входную строку заданной строкой.

3

tokenize ($ input, $ regex)

Возвращает последовательность элементов, соответствующих регулярному выражению.

XQuery предоставляет очень полезную конструкцию if-then-else для проверки действительности переданных входных значений. Ниже приведен синтаксис конструкции if-then-else.

Синтаксис

if (condition) then
 ... 
else
 ...

пример

Мы воспользуемся следующим файлом books.xml и применим к нему выражение XQuery, содержащее конструкцию if-then-else, чтобы получить заголовки тех книг со значением цены больше 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author>
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
</books>

Следующее выражение XQuery должно применяться к вышеуказанному XML-документу.

books.xqy

<result>
{
   if(not(doc("books.xml"))) then (
      <error>
         <message>books.xml does not exist</message>
      </error>
   )
   else ( 
      for $x in doc("books.xml")/books/book	
      where $x/price>30 return $x/title
   )
}
</result>

Вывод

<result>
   <title lang="en">Learn .Net in 24 hours</title>
   <title lang="en">Learn XQuery in 24 hours</title>
</result>

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.

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

  • Используйте ключевое слово declare function для определения функции.

  • Использовать типы данных, определенные в текущей схеме XML

  • Заключите тело функции в фигурные скобки.

  • Префикс имени функции с пространством имен XML.

При создании пользовательской функции используется следующий синтаксис.

Синтаксис

declare function prefix:function_name($parameter as datatype?...)
as returnDatatype?
{
   function body...
};

пример

В следующем примере показано, как создать пользовательскую функцию в XQuery.

Выражение XQuery

declare function local:discount($price as xs:decimal?,$percentDiscount as xs:decimal?) as xs:decimal? { let $discount := $price - ($price * $percentDiscount div 100) return $discount
};

let $originalPrice := 100 let $discountAvailed := 10

return ( local:discount($originalPrice, $discountAvailed))

Вывод

90

Проверить результат

Чтобы проверить результат, замените содержимое файла books.xqy (приведенное в главе « Настройка среды» ) указанным выше выражением XQuery и выполните java-программу XQueryTester.