3

I have the following structure with a variable number of elements on the 2nd level under root with unknown names:

<root>
 <A>text a</A>
 <B>text b</B>
</root>

I need a query that delivers the text of a specific element in the 2nd level. the name of the required element is the argument passed in by a user.

I already succeeded in finding it for example for element "A", querying the XML document stored in variable @x:

declare @str varchar(1000) = '<root><A>text a</A><B>text b</B></root>'
declare @x xml = convert(xml, @str)
SELECT xLangStruct.x.value('(A/text())[1]', 'varchar(100)') from @x.nodes('//root') as xLangStruct(x)

This works for "A", but now I need to replace "A" with a variable or any kind of filtering... So I need anything like that:

SELECT xLangStruct.x.value('(@SEARCHEDELEMENT/text())[1]', 'varchar(100)') from @x.nodes('//root') as xLangStruct(x)

or

SELECT xLangStruct.x.value('(./text())[1]', 'varchar(100)') from @x.nodes('//root') as xLangStruct(x) WHERE xLangStruct.x.Elementname = @SEARCHEDELEMENT
Erik Reasonable Rates Darling
46.4k14 gold badges146 silver badges542 bronze badges
asked Apr 6, 2017 at 14:03
1

1 Answer 1

1

While there's no messing with Mikael Eriksson when it comes to XML (he is, after all, my spiritual XML guide), here's an answer specific to your question.

You just have to change the way you're handling the XML a little bit. I also changed the XML a touch to rule out false positives searching for A and B in the node names to text 1 and text 2.

DECLARE @xmltable TABLE (xmlvalue XML)
INSERT @xmltable ( xmlvalue )
 VALUES ( '<root><A>text 1</A><B>text 2</B></root>' )
DECLARE @searchstring VARCHAR(100) = 'A'
SELECT x.*,
xa.c.value('.', 'VARCHAR(100)') AS [weird]
FROM @xmltable AS x
CROSS APPLY x.xmlvalue.nodes('/root/*[local-name()=sql:variable("@searchstring")]') xa (c)

This returns text 1.

DECLARE @xmltable TABLE (xmlvalue XML)
INSERT @xmltable ( xmlvalue )
 VALUES ( '<root><A>text 1</A><B>text 2</B></root>' )
 DECLARE @searchstring VARCHAR(100) = 'B'
 SELECT x.*,
 xa.c.value('.', 'VARCHAR(100)') AS [weird]
 FROM @xmltable AS x
 CROSS APPLY x.xmlvalue.nodes('/root/*[local-name()=sql:variable("@searchstring")]') xa (c)

This returns text 2.

answered Apr 6, 2017 at 14:53
2
  • Appreciate your time Erik! Your solution works perfectly. However, the solution linked in the comment above, which I unfortunately was not able to find on my own, looks more simple, doesn't it? Commented Apr 6, 2017 at 15:52
  • 1
    @Magier I don't know what your actual setup looks like, so that's hard to answer. I'd test both to see what you get for performance. Commented Apr 6, 2017 at 15:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.