1

I have a collection of 1000s of TEI documents in the variable $data (note: the top-most node in each document is tei:TEI).

Within Xpath (under Xquery) I can output all the @type="example" documents with:

let $coll := $data/tei:TEI[@type="example"]
return $coll

I can then further extract one document from the above result with:

let $coll := $data/tei:TEI[@type="example"]
return $coll[@xml:id="TC0005"]

The above work fine.

Now, I would like to get the documents before and after a certain document, which I assume could be done with preceding-sibling / following-sibling:

let $coll := $data/tei:TEI[@type="example"]
return ($coll[@xml:id="TC0005"]/preceding-sibling[1],
       $coll[@xml:id="TC0005"],
       $coll[@xml:id="TC0005"]/following-sibling[1])

However the above only returns the document for $coll[@xml:id="TC0005"].

Is this syntax correct for navigating document to document within the collection?

Many thanks.

jbrehr
  • 775
  • 6
  • 19

1 Answers1

2

In a collection or sequence of document nodes you don't have any siblings, siblings only exists in each document tree, so I think you simply want positional access in the form of

let $examples := $data/tei:TEI[@type="example"]
for $example at $pos in $examples
where $example/@xml:id = 'TC0005'
return (
  $examples[$pos - 1],
  $example
  $examples[$pos + 1]
)

That is based on my understanding of XQuery and XPath sequences, I hope it applies to your collection in an XQuery database as well.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • That does indeed work, thank you. Curiously it outputs doc 'TC0006' for `$pos - 1` and doc 'TC0004' for `$pos + 1`, which is the inverse of what I would expect. – jbrehr Aug 17 '19 at 16:00
  • 1
    How do you get `$data`, through the `collection` function? Does that return the various documents in a particular order. I think, if `$data` is a collection of document node, the step `/tei:TEI[@type="example"]` in `$data/tei:TEI[@type="example"]` might indeed leave it up to implementation as to which order to use (a step with `/` orders nodes from one document in the document order but nodes from different docs have no predefined order), so, if `$data` has the order you expect, it might be better to simply use `let $examples := $data ! tei:TEI[@type="example"]` instead. – Martin Honnen Aug 17 '19 at 16:06
  • Yes, I get `$data` through the collection function, and testing just now it outputs in descending alpha-numeric order (of document title). And I can't seem to get `order by` to override output order in this particular function. – jbrehr Aug 17 '19 at 16:18
  • 1
    It might better to raise the problem of the order of the collection result in a new, separate question where you add a tag for your database or XQuery processor as well as I think any such order is depending very much on the particular processor. – Martin Honnen Aug 17 '19 at 16:36
  • 1
    Correct, ordering of documents within a collection is very much processor-dependent. In fact, there are two orderings which aren't necessarily the same: the order of items in the sequence returned by the collection() function, and "document order". – Michael Kay Aug 17 '19 at 17:49