1

I stumbled over some odd behaviour in connection with prefixed attributes. I know - in general - that in most cases prefixed attributes are not used, as they belong to an element which is in a namespace already. But shortly I tried to answer a question and found something I could not understand, even after some research:

DECLARE @xml XML=
N'<test:root xmlns:test="SomeURL">
    <test:SomeElement test:SomeAttribute="yeah!" />
  </test:root>';

I can wildcard the namespace:

SELECT @xml.value(N'(/*:root/*:SomeElement/@*:SomeAttribute)[1]',N'nvarchar(max)');

I can give an alias to the namespace:

WITH XMLNAMESPACES('SomeURL' AS ns)
SELECT @xml.value(N'(/ns:root/ns:SomeElement/@ns:SomeAttribute)[1]',N'nvarchar(max)');

I thought - as there is only one namespace - I could use it as default:

WITH XMLNAMESPACES(DEFAULT 'SomeURL')
SELECT @xml.value(N'(/root/SomeElement/@SomeAttribute)[1]',N'nvarchar(max)'); --fails!

If I use the same as above but set a wildcard to the attribute it works:

WITH XMLNAMESPACES(DEFAULT 'SomeURL')
SELECT @xml.value(N'(/root/SomeElement/@*:SomeAttribute)[1]',N'nvarchar(max)');

When I use old fashioned FROM OPENXML I see, that the attribute is a member of test / SomeURL namespace, just as all elements:

DECLARE @hdoc INT;
EXEC sp_xml_preparedocument @hdoc OUTPUT, @xml;

SELECT * FROM OPENXML (@hdoc, '//*',3);  

EXEC sp_xml_removedocument @hdoc;

The result:

+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| id | parentid | nodetype | localname     | prefix | namespaceuri | datatype | prev | text    |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 0  | NULL     | 1        | root          | test   | SomeURL      | NULL     | NULL | NULL    |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 2  | 0        | 2        | test          | xmlns  | NULL         | NULL     | NULL | NULL    |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 5  | 2        | 3        | #text         | NULL   | NULL         | NULL     | NULL | SomeURL |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 3  | 0        | 1        | SomeElement   | test   | SomeURL      | NULL     | NULL | NULL    |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 4  | 3        | 2        | SomeAttribute | test   | SomeURL      | NULL     | NULL | NULL    |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 6  | 4        | 3        | #text         | NULL   | NULL         | NULL     | NULL | yeah!   |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+

This is a tiny issue, as it is easy to find a work around, but I'm curious...

Any light on this?

1 Answer 1

2

In XPath, as in XML, the default namespace does not apply to attributes. An element name written without a prefix assumes the default namespace, while an attribute name written without a prefix assumes "no namespace".

Sign up to request clarification or add additional context in comments.

1 Comment

This answer - uhm - just describes the obvious behaviour and yes, you are right completely. This might not be fully intuitive, but it is as it is. No further explanantion possible/necessary. Therefore thx, I'll mark this answer.

Your Answer

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.