Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the names of attributes from an element in a SQL XML column

For this xml (in a SQL 2005 XML column):

<doc>
 <a>1</a>
 <b ba="1" bb="2" bc="3" />
 <c bd="3"/>
<doc>

I'd like to be able to retrieve the names of the attributes (ba, bb, bc, bd) rather than the values inside SQL Server 2005. Well, XPath certainly allows this with name() but SQL doesn't support that. This is my chief complaint with using XML in SQL; you have to figure out which parts of the XML/Xpath/XQuery spec are in there.

The only way I can think of to do this is to build a CLR proc that loads the XML into an XML Document (iirc) and runs the XPath to extract the names of the nodes. I'm open to suggestions here.

like image 300
jcollum Avatar asked Oct 27 '08 21:10

jcollum


People also ask

How do I query an XML column in SQL Server?

SQL Server provides the XQuery feature to querying XML data type or querying with the XML column with the XPATH. Using XQuery, users can Insert, Update and Delete with the XML nodes and node values in an XML column.

How can I get SQL query results in XML?

You can optionally retrieve formal results of a SQL query as XML by specifying the FOR XML clause in the query. The FOR XML clause can be used in top-level queries and in subqueries. The top-level FOR XML clause can be used only in the SELECT statement.

How do you display attributes from a table in SQL?

To show table properties in the Properties window. In Object Explorer, select the table for which you want to show properties. Right-click the table and choose Properties from the shortcut menu. For more information, see Table Properties - SSMS.

How do I query XML data?

XML data can be queried using an SQL fullselect or with the SQL/XML query functions of XMLQUERY and XMLTABLE. The XMLEXISTS predicate can also be used in SQL queries on XML data.


2 Answers

DECLARE @xml as xml

SET @xml = 
'<doc>
 <a>1</a>
 <b ba="1" bb="2" bc="3" />
 <c bd="3"/>
</doc>'

SELECT DISTINCT
 CAST(Attribute.Name.query('local-name(.)') AS VARCHAR(100)) Attribute,
 Attribute.Name.value('.','VARCHAR(100)') Value
FROM @xml.nodes('//@*') Attribute(Name)

Returns:

Attribute Value

ba 1

bb 2

bc 3

bd 3

like image 151
Ben Davis Avatar answered Sep 28 '22 06:09

Ben Davis


DECLARE @xml as xml
DECLARE @path as varchar(max)
DECLARE @index int, @count int

SET @xml = 
'<doc>
 <a>1</a>
 <b ba="1" bb="2" bc="3" />
 <c bd="3"/>
</doc>'



SELECT @index = 1

SET @count = @xml.query('count(/doc/b/@*)').value('.','int')

WHILE @index <= @count 
BEGIN
    SELECT  @xml.value('local-name((/doc/b/@*[sql:variable("@index")])[1])', 'varchar(max)')
    SET @index = @index + 1
END

for element 'b'

it returns

  • ba
  • bb
  • bc

You can build a loop to get attributes for each element in the xml.

BTW The XML in your sample should be closed at closing doc tag.

like image 45
Ray Lu Avatar answered Sep 28 '22 07:09

Ray Lu