bethesdaboys
bethesdaboys

Reputation: 1827

How to get child elements but none of their children?

Using MarkLogic but this is probably a generic XQuery question.

I have:

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

I want to return all the [book] elements with their title attributes, but I do NOT want any of the children of book, e.g. [publisher]. How do I accomplish this in an orthodox and performant manner?

Correlated question: at times I may want to get some of the children, but not others, e.g. get all the book elements and their publisher child elements, but none of the other children.

Thanks.

Upvotes: 6

Views: 345

Answers (4)

Walt
Walt

Reputation: 83

I think a slightly better solution to Michael Kay's would be to not enumerate each desired attribute and make it slightly more general. The thing to note is that /@ returns an attribute and not just text.

For instance:

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

or even more generally:

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

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163458

The XQuery (actually an XPath, which is a subset of XQuery) /library/books/book technically does what you want - it returns a set of book elements, and nothing else. Some APIs will return references to the book elements, and leave you to decide what you want to do with them, for example displaying their titles. However, many tools and APIs will copy these book elements together with the whole subtree rooted at the book, and in the case of a database, this is very often the result that will be transmitted over the network from the server to the client. In this case you don't want to select the existing book elements, you want to construct a new document containing a subset of the information in the book elements. To do this you can use element constructors in XQuery:

for $b in /library/books/book
return <book title="{$b/@title}"/>

Upvotes: 5

Eric Bloch
Eric Bloch

Reputation: 2961

There are probably easier ways... but I think something like this will copy the attributes w/out the other children. Warning: code untested

for $i in doc()//book
return <book>{
    for $a in $i/@*
    return $a
}</book>

Upvotes: 2

kmehta
kmehta

Reputation: 2497

Check out XQuery select syntax at the link below. Select syntax usually allows you to grab the data elements that you are interested in, format it how you want, and omit stuff you don't care about.

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

Upvotes: 0

Related Questions