user3281388
user3281388

Reputation: 267

XQuery or XPath expression explained

Could someone break down what this Xquery is doing?

'for $i in . return count(../*[. << $i])'

I can tell it is a for loop, but I am confused by the ../* and the []. It is in this SQL code that I'm working on. I am trying to extract column-name nodes from an XML file:

    SELECT distinct 
    Parent.Items.value('for $i in . return count(../*[. << $i])', 'int') as [Index],
    Parent.Items.value('local-name(../.)', 'varchar(100)') as 'ParentItem',
    Parent.Items.value('local-name(.)', 'varchar(100)') as 'ChildItem'
    FROM    dbo.MyFormResults
    CROSS APPLY xmlformfields.nodes('/form/*')  as Parent(Items)

I want this Xquery to iterate through my XML nodes in the order they are in my XML file. It sort of works, but it double counts and I'm not sure why... maybe if i understand this loop better I can fix my problem.

enter image description here

As you can see here Indexes: 15, 16 and 17 are duplicated.

Thanks!

Upvotes: 0

Views: 106

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122364

for $i in .

A for $x in y return z expression assigns the variable $x to each item in the sequence y in turn and evaluates the expression z, returning a sequence which is the concatenation of all the results from the evaluations of z, e.g. for $i in (1, 2, 3) return (2 * $i) would generate the sequence (2, 4, 6).

In this case the sequence y is just a single node - it's an idiom to capture the current value of . in a variable so you can make use of it in deeper predicates, as an alternative to the XSLT current() function when you're working with XPath 2.0 outside of XSLT.

../*[. << $i]

the << operator tests the relative position of nodes, x << y is true if x comes before y in document order.

Therefore for $i in . return count(../*[. << $i]) is simply a long-winded way of writing count(preceding-sibling::*) - the number of sibling elements of the current node (., which is also known as $y) that come before that node in document order.

Upvotes: 3

Related Questions