Is it possible to reference the current context node in a nodes()
's XQuery statement?
Example
Suppose I have XML data sorted in a table/table variable where one section of each document references an element in another section by an attribute. (In the below, person and position are associated by ID.)
DECLARE @Data TABLE (
ID INT NOT NULL PRIMARY KEY,
XmlData XML NOT NULL
)
INSERT INTO @Data
VALUES (1, '<Root>
<People>
<Person id="1">Frank</Person>
<Person id="2">Joe</Person>
</People>
<Positions>
<Position assignedToPerson="1">Engineer</Position>
<Position assignedToPerson="2">Manager</Position>
</Positions>
</Root>'),
(2, '<Root>
<People>
<Person id="5">Bob</Person>
<Person id="6">Sam</Person>
</People>
<Positions>
<Position assignedToPerson="6">Mechanic</Position>
<Position assignedToPerson="5">Accountant</Position>
</Positions>
</Root>')
A resultset of person-position pairings can be produced like this:
SELECT
PersonID = person.value('@id', 'NVARCHAR(50)'),
Name = person.value('.', 'NVARCHAR(50)'),
Position = position.value('.', 'NVARCHAR(50)')
FROM @Data
CROSS APPLY XmlData.nodes('/Root/People/Person') People(person)
CROSS APPLY person.nodes('/Root/Positions/Position') Positions(position)
WHERE person.value('@id', 'NVARCHAR(50)')= position.value('@assignedToPerson[1]','NVARCHAR(50)')
+----------+-------+------------+ | PersonID | Name | Position | +----------+-------+------------+ | 1 | Frank | Engineer | | 2 | Joe | Manager | | 5 | Bob | Accountant | | 6 | Sam | Mechanic | +----------+-------+------------+
Problem
The second CROSS APPLY
breaks out each position defined in the relevant XML document into its own row each time it's called. The result is that each person in a document is paired with each position defined in the document. Filtering the resultset down to related person-position pairs occurs in the WHERE
clause.
Goal
I'd like to eliminate the matching all people to every position by referencing the context node of People(person)
in the second XQuery--something like this:
SELECT
PersonID = person.value('@id', 'NVARCHAR(50)'),
Name = person.value('.', 'NVARCHAR(50)'),
Position = position.value('.', 'NVARCHAR(50)')
FROM @Data
CROSS APPLY XmlData.nodes('/Root/People/Person') People(person)
CROSS APPLY person.nodes('/Root/Positions/Position[@assignedToPerson={{**reference to @ID of context node**}}]') Positions(position)
Can I reference the first nodes()
context node in the second CROSS APPLY
's XQuery?
(Using a JOIN-based approach doesn't work as the data for the above comes from a table, not an XML variable.)