У меня есть следующий код XQuery в редакторе BaseX, но он содержит ошибки в предложении if, заявляя
Неполное выражение FLWOR: ожидается "возврат"
Код, который я пытаюсь использовать:
import module namespace functx = 'http://www.functx.com';
declare namespace file = "http://expath.org/ns/file";
let $root := 'E:\basex-index-testing\sonar-small\index'
let $ds := file:dir-separator()
(: get files in sonar-small database :)
for $f in db:list('sonar-small')
(: remove *.xml from doc name :)
let $corpus := substring($f, 1, string-length($f) - 4)
for $alpino in db:open('sonar-small', $f)/treebank/alpino_ds
(: make sure tree has sentence element :)
where count($alpino/sentence) > 0
let $sentenceId := data($alpino/@id)
for $node in $alpino//node
(: make sure there are less than 500 descendants,
less than 100 and more than 0 children :)
where count($node//node) < 500 and count($node/node) > 0
and count($node/node) < 100
let $catTop := data($node/@cat)
(: create indexing pattern based on node's direct children :)
let $childrenRelCat := ()
for $child in $node/node
let $childRel := data($child/@rel)
(: use children's cat or pt attribute, default to '' :)
let $childCat := data($child/(@cat, @pt, '')[1])
(: concatenate childrenRelCat sequence (append to list) :)
let $childrenRelCat := ($childrenRelCat,
string-join(($childRel, $childCat), '%'))
let $bf := string-join(functx:sort($childrenRelCat), '_')
let $sent := <tree id="{$sentenceId}">{$node}</tree>
let $dir := concat($root, $ds, $catTop)
(: this if-clause throws an error: missing return statement,
incomplete FWLOR:)
if (file:exists($dir) and file:is-dir($dir))
then ()
else file:create-dir($dir)
(: append subtree to pattern-file :)
file:append($dir || $bf || '-index.xml', $sent)
(: doesn't have to return anything, but FWLOR demands it... :)
return $f
Кажется, я упускаю что-то важное в том, как XQuery оценивает выражения или ожидает, что они будут упорядочены. Что не так в коде выше?
(Этот вопрос называется почти идентично, но приведенный там ответ не помогает, так как там была еще одна ошибка в коде этого ОП.)
let
должен следоватьreturn
. Я не уверен, чего вы хотите добиться с помощью всего выражения, какreturn 5
относится к созданию файла? - person Martin Honnen   schedule 15.04.2018return None
, когда вы не хотите ничего возвращать? - person Bram Vanroy   schedule 16.04.2018let $dir := 'hello/world' return if (file:exists($dir) and file:is-dir($dir)) then () else file:create-dir($dir)
делать то, что вы хотите, например. разрешить вам сохранить имя файла, а затем использовать его в выраженииif
? Я до сих пор не уверен, что вы хотите делать сreturn 5
(и я не проверял, возвращает ли что-тоfile:create-dir
). - person Martin Honnen   schedule 16.04.2018return $file
, хотя эта переменная никогда не объявлялась и не была привязана к значению. В общем, проблема в том, чтоlet
всегда должен быть частью w3. .org/TR/xquery-31/#doc-xquery31-FLWORExpr с выражениемreturn
иif
не может быть начальным или промежуточным предложением такого FLOWRExpr, оно может быть только в предложенииreturn
или использоваться внутри изlet
(например,let $foo := if (...) then ... else ...
) илиfor
(например,for $bar in (if (...) then ... else ...)
). - person Martin Honnen   schedule 16.04.2018$f
. Не странная конструкция? Я не привык к XQuery, и это меня очень сбивает с толку. Но принуждение к использованию объявлений переменных не должно быть очень эффективным с точки зрения использования памяти, верно? Как бы вы переписали мое if-оператор? Я не вижу разумного способа включить оператор в return или let-декларацию. - person Bram Vanroy   schedule 16.04.2018if
может появиться, а где нет, и каковы правила построения выражения FLOWR. Что касается переписывания кода разрешенным способом, я думаю, что один из способов будетlet $dir := concat($root, $ds, $catTop) return (if (file:exists($dir) and file:is-dir($dir)) then () else file:create-dir($dir), file:append($dir || $bf || '-index.xml', $sent))
. - person Martin Honnen   schedule 16.04.2018