Точно так же, как навигация по файловой системе (или любой другой древовидной структуре), нам нужно знать наше место в этой структуре, чтобы иметь возможность использовать выражения пути:
/home/logname/documents/work #> cd todo
/home/logname/documents/work/todo #>
Как выполнялась командаЛинейный интерпретатор знает, где найти каталог todo ?Он знал это, потому что по соглашению предполагал, что контекстом для команды cd
будет текущий каталог , в данном случае /home/logname/documents/work
.
Когда вы загружаетедокумент / база данных в BaseX, он делает то же самое для выражений XPath и XQuerys, если контекст понятен.Если, например, вы поместите одну точку .
в редакторе запросов, а затем выполните этот запрос, он вернет вам весь документ, поскольку именно это означает .
: текущий элемент контекста .Здесь BaseX знает этот контекст из соглашения, что он по умолчанию выполняет запросы к текущему загруженному документу, точно так же, как интерпретатор командной строки принимает текущий каталог в качестве текущего контекста.Можно сказать, что, загружая документ / базу данных, вы cd
'врезались в корень этого документа.Пока все хорошо ...
Как только вы используете XQuery, вы используете полный язык программирования, который позволяет делать гораздо больше, чем просто запрашивать отдельные документы.Вы можете запросить целую кучу документов в одном скрипте.
Взять этот (неполный) фрагмент кода:
let $db := db:open("list")
let $db2 := db:open("list2")
Если вы теперь размещаете запросы так, как делали, куда они идут?Используют ли они $db
в качестве контекста или $db2
?
Что вам нужно сделать, это сообщить процессору об этом.Это можно сделать несколькими способами:
- в прологе вашего скрипта:
declare context item := db:open("list");
(см. Также: Документация BaseX по этому и, что очень важно,, читайте о разнице между "статическим контекстом" и "динамическим контекстом" здесь ), чтобы узнать больше о контексте в целом. - в самом выражении XPath:
let $db := db:open("list")
return $db/root()/descendant::li/a/text()
или, упрощенно:
let $db := db:open("list")
return $db//li/a/text()
или:
declare context item := db:open("list");
.//li/a/text()