Не удается перебрать элементы в XML-файле с помощью xquery

У меня есть файл xml с такой структурой:

<profiles>
    <profile profile="SuperAdministrator" name="admin"/>
    <profile project="TesteHandSpy" profile="Researcher" name="john"/>
    <profile project="DunnProject,DAAR1_op,Sara" profile="Researcher" name="juliete"/>
</profiles>

И я хочу выбрать значение проекта элементов профиля с определенным значением имени атрибута. Я начал пытаться просто перечислить все элементы профиля, и у меня возникли проблемы с этим. Я могу найти файл, но затем я использую команды, которые я нашел в нескольких местах, и он возвращает нулевые результаты. Вот xquery, который я тестирую:

let $param := "juliete"
let $profiles:= doc("/db/db_project/profiles.xml")/profiles/profile

for $profile in $profiles
return $profile

Можешь мне помочь? Я думаю, когда это начнет работать, все, что мне нужно сделать, это добавить [@name=$param] в запрос.


person patricia    schedule 12.05.2015    source источник
comment
Какой процессор? Вы уверены, что путь правильный? Используемый вами xquery правильно отображает все профили.   -  person Ewout Graswinckel    schedule 12.05.2015
comment
@EwoutGraswinckel, если я удалю /profiles/profile, он покажет содержимое моего файла, так что я думаю, это означает, что мой путь правильный. Я также пытался поставить //профиль, и это не сработало.   -  person patricia    schedule 12.05.2015
comment
@EwoutGraswinckel Я пробую это на eXist-db с xquery 3.0   -  person patricia    schedule 12.05.2015
comment
если ваше выражение XPath не выбирает никаких элементов, но документ возвращается, скорее всего, у вас несоответствие пространства имен. Определены ли в вашем документе пространства имен (xmlns="...")?   -  person joemfb    schedule 12.05.2015
comment
@joemfb да, у меня есть это: xmlns=dcc.fc.up.pt/DAAR/HandSpy в ‹профилях›   -  person patricia    schedule 17.05.2015


Ответы (1)


Здесь нет необходимости в выражении FLOWR. Простой путь подойдет:

doc("/db/db_project/profiles.xml")/profiles/profile[@name eq $param]

То, что это вернуть ничего не может быть по нескольким причинам. Наиболее очевидными являются: 1) неправильный URI (попробуйте вызвать doc() с тем же URI, чтобы убедиться, что он возвращает документ) или 2) проблема с пространством имен (вы можете попробовать *:profiles/*:profile, чтобы убедиться, что это не так).

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

Обновить

После вашего комментария кажется, что это проблема пространства имен. Таким образом, ввод XML, который вы цитировали выше, не совсем корректен. Ему не хватает пространства имен, например:

<profiles xmlns="http://example.org/project">
   ...
</profiles>

Путь типа /profiles/profile возвращает элементы profile, дочерние элементы элемента profiles, все в НЕТ пространстве имен. Чтобы получить доступ к ним в определенном пространстве имен, вы должны сначала привязать префикс к URI этого пространства имен, а затем использовать префикс для каждого имени элемента:

declare namespace p = "http://example.org/project";
doc("/db/db_project/profiles.xml")/p:profiles/p:profile[@name eq $param]

Вы должны понимать, что префикс, используемый в запросе (в данном случае p), и тот, который используется в XML (в данном случае без префикса, поскольку URI привязан как пространство имен по умолчанию), не обязательно должны совпадать. URI, которые они оба должны совпадать.

person Florent Georges    schedule 12.05.2015
comment
Спасибо, с :profiles/:profile xquery работает. Можете ли вы просто объяснить мне, почему /profiles/profile не работает? - person patricia; 17.05.2015
comment
Спасибо вам за разъяснение :) - person patricia; 26.05.2015