How can the following statement best be modified so that I receive a list of Contact.Name with Address.Location (I’d like to use XPath and not subqueries/WHERE-conditions if possible)? I’ve tried all sorts of syntax at @@@Name but no luck 🙁 – I want to reference the original node there.
DECLARE @data AS XML
SELECT @data = '
<Data>
<Contact Name="John"/>
<Contact Name="Bob"/>
<Address ContactName="John" Location="JohnStreet1"/>
<Address ContactName="John" Location="JohnStreet2"/>
<Address ContactName="Bob" Location="BobStreet1"/>
</Data>
'
SELECT
x.v.value('@Name','VARCHAR(255)') [Contact.Name],
y.v.value('@Location','VARCHAR(255)') [Address.Location]
FROM
@data.nodes('/Data[1]/Contact') AS x(v)
CROSS APPLY
x.v.nodes('/Data[1]/Address[@ContactName=@@@Name]') AS y(v)
ORDER BY
x.v.value('@Name','VARCHAR(255)')
PS. This won’t work since the parameter needs to be a literal 🙁
x.v.nodes('/Data[1]/Address[@ContactName=' + x.v.value('@Name','VARCHAR(255)') + ']') AS y(v)
Please note: Currently I’m doing the following to get the desired resultset (but not in a clean XPath way):
SELECT
x.v.value('@Name','VARCHAR(255)') [Contact.Name],
y.v.value('@Location','VARCHAR(255)') [Address.Location]
FROM
@data.nodes('/Data[1]/Contact') AS x(v)
CROSS APPLY
x.v.nodes('/Data[1]/Address') AS y(v)
WHERE
y.v.value('@ContactName','VARCHAR(255)')=x.v.value('@Name','VARCHAR(255)')
ORDER BY
x.v.value('@Name','VARCHAR(255)')
Here is a pure XQuery (which also happens to be a pure XPath 2.0 expression):
When this XPath expression is evaluated against the provided XML document:
the wanted, correct result is produced:
Do Note:
This is a pure XQuery / XPath 2.0 solution. I don’t know the SQL Server XQuery dialect and hope that you would be able to apply this solution to your case.
Probably something like:
Update:
As noted in a comment by Mikael Eriksson, SQL Server XQuery doesn’t accept “heterogeneous sequences” and raises an error.
Then this, slightly modified query works:
and produces the above wanted, correct result.