Как получить дочерние элементы, но не их дочерние элементы?

Используя MarkLogic, но это, вероятно, общий вопрос XQuery.

У меня есть:

<library>
  <books>
    <book title="whatever">
      <publisher>Random</publisher>
      ....more children
    </book>
    <book title="another">
      <publisher>Simon</publisher>
      ....more children
    </book>
    ...
  </books>
</library>

Я хочу вернуть все элементы [book] с их атрибутами title, но я НЕ хочу, чтобы какие-либо дочерние элементы book, например. [издатель]. Как мне добиться этого ортодоксальным и действенным образом?

Связанный вопрос: иногда я могу захотеть получить некоторых дочерних элементов, но не других, например. получить все элементы книги и их дочерние элементы издателя, но ни один из других дочерних элементов.

Спасибо.


person bethesdaboys    schedule 21.10.2011    source источник


Ответы (4)


XQuery (фактически XPath, который является подмножеством XQuery) /library/books/book технически делает то, что вам нужно — он возвращает набор элементов книги и ничего больше. Некоторые API возвращают ссылки на элементы книги и оставляют вам решать, что вы хотите с ними делать, например отображать их названия. Однако многие инструменты и API будут копировать эти элементы книги вместе со всем поддеревом, корнем которого является книга, и в случае с базой данных очень часто результат будет передаваться по сети от сервера к клиенту. В этом случае вы не хотите выбирать существующие элементы книги, вы хотите создать новый документ, содержащий подмножество информации в элементах книги. Для этого вы можете использовать конструкторы элементов в XQuery:

for $b in /library/books/book
return <book title="{$b/@title}"/>
person Michael Kay    schedule 21.10.2011
comment
Спасибо, Майкл! На мой взгляд, это самый элегантный подход, учитывая другие рекомендации. - person bethesdaboys; 23.10.2011

Вероятно, есть более простые способы... но я думаю, что что-то вроде этого скопирует атрибуты без других детей. Предупреждение: код не проверен

for $i in doc()//book
return <book>{
    for $a in $i/@*
    return $a
}</book>
person Eric Bloch    schedule 21.10.2011
comment
Спасибо, это полезно, поскольку дает мне представление о более общем подходе. - person bethesdaboys; 23.10.2011

Я думаю, что немного лучшим решением для Майкла Кея было бы не перечислять каждый желаемый атрибут и сделать его немного более общим. Следует отметить, что /@ возвращает атрибут, а не только текст.

Например:

for $book in /library/books/book return <book>{$book/@*}</book>

или даже в более общем виде:

for $book in /library/books/book return element book {$book/@*}
person Walt    schedule 21.11.2011
comment
Вы также не должны использовать for. Вы можете просто использовать такое выражение пути: /library/books/book/‹book›{@*}‹/book› - person Evan Lenz; 22.11.2011
comment
Мне нравится простота такого подхода. Однако моей первой реакцией было, почему у вас есть элемент в вашем x-пути? Думаю, я возьму этот подход. Спасибо. - person Walt; 18.09.2012

Ознакомьтесь с синтаксисом выбора XQuery по ссылке ниже. Синтаксис select обычно позволяет вам захватывать интересующие вас элементы данных, форматировать их так, как вы хотите, и опускать то, что вам не нужно.

http://www.w3schools.com/xquery/xquery_select.asp

person kmehta    schedule 21.10.2011