I have xml stored in a table and table with names/paths of the elements I am interested in.
I would like to extract values of these elements without hard coding paths and/or names of the elements. Structure of my xml will not change, it will always have parent/child/element.
Is it possible to join xml and table to get to the values of the elements?
Below is example of what I was able to get. I think it is possible to extend this solution to JOIN on ChildNode and Element but not sure how to use .query() and .value() to get to ChildNode and Element.
Thank you for your help.
DECLARE @xml xml
SET @xml =
'<Products>
<RedProduct>
<Details_RedProduct>
<Width>1</Width>
<Depth>2</Depth>
<Weight>3</Weight>
</Details_RedProduct>
</RedProduct>
<GreenProduct>
<Details_GreenProduct>
<Width>4</Width>
<Depth>5</Depth>
<Height>6</Height>
</Details_GreenProduct>
</GreenProduct>
<BlueProduct>
<Details_BlueProduct>
<Width>7</Width>
<Depth>8</Depth>
<Lenght>9</Lenght>
</Details_BlueProduct>
</BlueProduct>
</Products>'
DECLARE @ProductElement table (ProductNode nvarchar(100), ChildNode nvarchar(100), Element nvarchar(20))
INSERT INTO @ProductElement SELECT 'RedProduct','','Width'
INSERT INTO @ProductElement SELECT 'GreenProduct','','Width'
INSERT INTO @ProductElement SELECT 'GreenProduct','','Height'
UPDATE @ProductElement SET ChildNode = 'Details_' + ProductNode
SELECT ProductsCollection.query('local-name(.)').value('.','nvarchar(100)') as TestOutput
FROM @xml.nodes('//Products/*') productsXml (ProductsCollection)
INNER JOIN @ProductElement el ON el.ProductNode = ProductsCollection.query('local-name(.)').value('.','nvarchar(100)')
You can use sql:column() in your xquery expression and compare against
local-name(.)to get the nodes you want.Result:
Edit:
Another version that uses a join on fields instead. It might have a better performance for you depending on what your data looks like. The first version parses the XML for each row in @ProductElement and the second version shreds the XML and uses that to join against @ProductElement.