Этот запрос, чтобы найти книги с автором ИЛИ соавтором, содержащие «Достоевский» и заголовок, содержащий «Братья» с языком «en», работает (т.е. дает ожидаемые результаты), но если есть лучший способ написать это, я 'm все уши:
/catalog//book/*[(contains(self::author,'Dostoyevsky') or contains(self::contributor,'Dostoyevsky')) and
содержит (../ title, 'Brothers') и ../@lang = 'en']
Выражение XPath выше не являетсятолько совершенно несовершенный, абсолютно неформатированный и нечитаемый, но, что более важно, он вообще не (как указано) выбирает какой-либо элемент book
(он может выбирать author
).Кроме того, псевдооператор //
не является необходимым и может значительно снизить эффективность оценки XPath для любого реального XML-документа среднего и большого размера.
Вот выражение XPath, которое выбирает то, что выwant :
/catalog/book
[@lang='en'
and
file/type='PDF'
and
*[self::author
or
self::contributor
]
[contains(., 'Dostoyevsky')]
and
contains(title, 'Brothers')
]
О, и, если это имеет значение, запрос должен быть построен динамически (из ввода формы), поэтому он должен сохранять универсальный синтаксис, который будет работать с любымчисло предоставленных пользователем критериев.
Этот "универсальный синтаксис может выглядеть примерно так:
/*/book
[
contains(*[name() = $pName1], $pString1)
and
contains(*[name() = $pName2], $pString2)
. . . . . .
and
contains(*[name() = $pNameK], $pStringK)
]
где $pName1
, $pName2
, ..., $pNameK
должны быть заменены именами полей, указанных конечным пользователем в форме поиска, а
$pString1
, $pString2
, ..., $pStringK
должны быть заменены данными, которыеуказанный пользователем должен содержаться в соответствующих полях.