Вы можете использовать sql: column () в выражении xquery и сравнить с local-name(.)
, чтобы получить нужные вам узлы.
select PE.ProductNode,
PE.ChildNode,
PE.Element,
T.Col.value('.', 'int') as ElementValue
from @ProductElement as PE
cross apply @xml.nodes('/Products/*[local-name(.) = sql:column("PE.ProductNode")]
/*[local-name(.) = sql:column("PE.ChildNode")]
/*[local-name(.) = sql:column("PE.Element")]') as T(Col)
Результат:
ProductNode ChildNode Element ElementValue
-------------------- -------------------- -------------------- ------------
RedProduct Details_RedProduct Width 1
GreenProduct Details_GreenProduct Width 4
GreenProduct Details_GreenProduct Height 6
Редактировать: Другая версия, в которой вместо этого используется объединение полей.Это может иметь лучшую производительность для вас в зависимости от того, как выглядят ваши данные.Первая версия анализирует XML для каждой строки в @ProductElement, а вторая версия разбивает XML и использует его для объединения с @ ProductElement.
select PE.ProductNode,
PE.ChildNode,
PE.Element,
X.ElementValue
from @ProductElement as PE
inner join (
select T1.Col.value('local-name(.)', 'varchar(100)') as ProductNode,
T2.Col.value('local-name(.)', 'varchar(100)') as ChildNode,
T3.Col.value('local-name(.)', 'varchar(100)') as Element,
T3.Col.value('.', 'varchar(100)') as ElementValue
from @xml.nodes('/Products/*') as T1(Col)
cross apply T1.Col.nodes('*') as T2(Col)
cross apply T2.Col.nodes('*') as T3(Col)
) as X
on PE.ProductNode = X.ProductNode and
PE.ChildNode = X.ChildNode and
PE.Element = X.Element