Пример вычисления выражения XQuery не является последовательным - PullRequest
3 голосов
/ 18 октября 2019

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

Например, в XQuery, 2-е издание , в следующем разделе:

FLWORВыражение with с предложением for похоже на циклы в процедурных языках, таких как C. Однако, одно ключевое отличие состоит в том, что в XQuery, поскольку это функциональный язык, итерации считаются в произвольном порядке. Они не обязательно происходят последовательно, один за другим.

Ответы [ 2 ]

6 голосов
/ 18 октября 2019

В общем, язык разработан так, что вы не можете определить порядок оценки, что затрудняет демонстрацию того, что это не то, что вы ожидаете. Чтобы соблюсти фактический порядок оценки, вам нужно сделать что-то, что имеет побочные эффекты, что обычно означает отклонение от спецификации языка и использование расширений поставщика. Например, вы можете использовать файловый модуль EXPath и вызывать вызовы file:append-text(), а затем проверить порядок записей, добавляемых во внешний текстовый файл.

Конечно, ничего не будет доказано, если записи вфайл в том порядке, в котором вы ожидаете. Обработчики запросов не собираются использовать неочевидный порядок выполнения просто для удовольствия. Они будут делать это только в том случае, если есть что-то, что можно получить, изменив порядок. Saxon, например, будет откладывать вычисление переменных до тех пор, пока они не будут использованы, и будет выводить выражения из цикла, если это возможно. Но тогда возникает проблема: если вы используете функции с побочными эффектами, такими как file:append-text(), чтобы наблюдать это поведение, Saxon может обнаружить, что ваш код имеет побочные эффекты, и подавить оптимизацию.

2 голосов
/ 18 октября 2019

В некоторых реализациях вы можете столкнуться с тем, что порядок результата в более сложных выражениях FLOWR является произвольным, например, на примере из книги Присциллы Уолмсли http://www.datypic.com/books/xquery/ группировка item элементов ('order.xmlв http://www.datypic.com/books/xquery/chapter01.html) с

<order num="00299432" date="2015-09-15" cust="0221A">
  <item dept="WMN" num="557" quantity="1" color="navy"/>
  <item dept="ACC" num="563" quantity="1"/>
  <item dept="ACC" num="443" quantity="2"/>
  <item dept="MEN" num="784" quantity="1" color="white"/>
  <item dept="MEN" num="784" quantity="1" color="gray"/>
  <item dept="WMN" num="557" quantity="1" color="black"/>
</order>

в саксонском 9,8 ОН с кодом (7,11 в http://www.datypic.com/books/xquery/chapter07.html)

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare option output:method 'xml';
declare option output:indent 'yes';

for $item in //item
group by $d:= $item/@dept, $n:= $item/@num
return <group dept="{$d}" num="{$n}" count="{count($item)}"/>

дает выход

<?xml version="1.0" encoding="UTF-8"?>
<group dept="ACC" num="563" count="1"/>
<group dept="MEN" num="784" count="2"/>
<group dept="WMN" num="557" count="2"/>
<group dept="ACC" num="443" count="1"/>

в то время как, например, с BaseX вы можете получить другой порядок вывода (я думаю, что на основе порядка ввода элементов, если я правильно помню) для элементов group, например, в BaseX 9, я получаю

<group dept="WMN" num="557" count="2"/>
<group dept="ACC" num="563" count="1"/>
<group dept="ACC" num="443" count="1"/>
<group dept="MEN" num="784" count="2"/>
...