Search code examples
xmlxsdxquerymarklogicxquery-sql

MarkLogic: XQuery to Get Values from XML Documents?


I have the following XML document loaded in MarkLogic database:

<x:books xmlns:x="urn:books">
  <book id="bk001">
    <author>Writer</author>
    <title>The First Book</title>
    <genre>Fiction</genre>
    <price>44.95</price>
    <pub_date>2000-10-01</pub_date>
    <review>An amazing story of nothing.</review>
  </book>
  <book id="bk002">
    <author>Poet</author>
    <title>The Poet's First Poem</title>
    <genre>Poem</genre>
    <price>24.95</price>
    <review>Least poetic poems.</review>
  </book>
</x:books>

I am new to XQuery. How would I retrieve the values from the XML document as I retrieve it from a SQL database?

Output:

BookID | Author | Title | Genre | price | pub_date | review
bk001 | Writer | The First Book | Fiction | 44.95 | 2000-10-01
bk002 | Poet | The Poet's First Poem | Poem | 24.95 | Least poetic poems.

Note: Not necessary a pipe delimited but some collection list.

Can some one share some link or help me write this XQuery? I am new to this.


Solution

  • XQuery's sequence construct will hold multiple values, but it's not hierarchical - so if you create a sequence of sequences, it will simply join them all together into one large sequence.

    This will capture all child element and attribute values into a sequence, but because of the property of sequences I just mentioned, there would be no built in way to get the first value of the second book. You would have to know that it's the 7th item. And that the first value of a third book would be the 14th item, and so on:

    $books/book/(*|@*)/string()
    

    Just to demonstrate how you would achieve a pipe delimited list:

    string-join($books/book[1]/(*|@*)/node-name() ! string(), ' | '), (: Create header row :)
    for $book in $books/book
    return string-join($book/(*|@*)/string(), ' | ')