XML默认命名空间和前缀属性

时间:2017-03-28 16:14:24

标签: sql xml tsql attributes xml-namespaces

我偶然发现了一些与前缀属性相关的奇怪行为。我知道 - 一般来说 - 在大多数情况下,不使用前缀属性,因为它们属于已经在命名空间中的元素。但不久我试着回答一个问题,发现了一些我无法理解的东西,即使经过一些研究:

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

我可以使用命名空间:

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

我可以为命名空间命名:

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

我想 - 因为只有一个名称空间 - 我可以将其用作默认名称:

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

如果我使用与上面相同的内容,但为其工作的属性设置了通配符:

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

当我使用旧式FROM OPENXML时,我看到该属性是test / SomeURL命名空间的成员,就像所有元素一样:

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

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

EXEC sp_xml_removedocument @hdoc;

结果:

+----+----------+----------+---------------+--------+--------------+----------+------+---------+
| 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!   |
+----+----------+----------+---------------+--------+--------------+----------+------+---------+

这是一个很小的问题,因为很容易找到解决方法,但我很好奇......

对此有何看法?

1 个答案:

答案 0 :(得分:2)

在XPath中,与在XML中一样,默认命名空间不适用于属性。没有前缀的元素名称假定为默认名称空间,而没有前缀的属性名称则假定为“无名称空间”。