SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 

XQuery – Accessing the Attributes Axis

Working with a sequence of attributes in XQuery is fairly straight forward with the “attribute” axis even if you don’t know or need to know the attribute names. By using this axis you can access all of the attributes within the given context node. The specific scenario I had was to find a particular duplicated node within the xml that had no attributes and delete it thus keeping the other node that I knew had attributes.

In this particular case i used the count() function as part of the predicate of an XML delete statement but getting a sequence of attributes could be useful in a variety of other use cases.

For example, the following is a contrived example of an XML structure and a query that shreds the XML and for each <SomeElement> node, counts the number attributes withint that node.

DECLARE @xml XML
SET @xml = '
<Data>
	<SomeElement This="123" That="456">This element has attributes</SomeElement>
	<SomeElement>This element does not</SomeElement>
	<SomeElement TheOther="7890">This element has one</SomeElement>
</Data>
'

SELECT t.c.query('.') AS 'SomeElement'
	, t.c.value('count(attribute::*)', 'int') AS 'CountOfAttributes'
FROM @xml.nodes('/Data/SomeElement') t(c)

Returns:

image

To access the attributes axis all you need to use is “attribute::” as part of the expression. I used “*” to denote all attributes within the context node. So by passing in all the attributes to the count() function, we can easily count them.

With this you can easily add predicates on the attributes to filter by the attribute name (local-name() function) or value (data() function) and is particularly useful if for whatever reason you may not know all of the attributes names.

To take it one step further, the following example takes the XML in the previous query and by using a FLWOR statement, returns all of the attributes in the entire XML as elements within a new XML structure:

SELECT @xml.query('
<AllAttributes>
	{
		for $x in //attribute::* return
			<Attribute>
				<Name>{local-name($x)}</Name>
				<Value>{data($x)}</Value>
			</Attribute>
	}
</AllAttributes>
')

Returns:

image

Enjoy!

Follow me on twitter @sqlserverrocks

Subscribe to my blog RSS feed

Comment on this or any of my posts or contact me directly from http://www.olcot.co.uk

SQL Server Rocks!

SQL Database Administrator/Developer. Background in developing OLTP/document based databases, SQLXML and performance tuning with an unhealthy fascination for the SQL query optimiser!

Comments

Leave a comment on the original post [www.olcot.co.uk, opens in a new window]

Loading comments...