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



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

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

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

对此有什么看法吗?

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

最新更新