与 QName 相关的函数 - expanded-QName
适用范围:SQL Server
返回 xs:QName 类型的值,其中包含$paramURI中指定的命名空间 URI 和$paramLocal中指定的本地名称。 如果 $paramURI 为空字符串或空序列,则表示无命名空间。
语法
fn:expanded-QName($paramURI as xs:string?, $paramLocal as xs:string?) as xs:QName?
参数
$paramURI
QName 的命名空间 URI。
$paramLocal
QName 的本地名称部分。
注解
以下内容适用于 expanded-QName() 函数:
如果指定的$paramLocal值不是 xs:NCName 类型的正确词法形式,则返回空序列并表示动态错误。
SQL Server 不支持从 xs:QName 类型转换为任何其他类型。 因此, 扩展 QName() 函数不能用于 XML 构造。 例如,当构造节点(如
<e> expanded-QName(...) </e>
)时,其值就必须是非类型化的。 这就要求您将expanded-QName()
返回的 xs:QName 类型值转换为 xdt:untypedAtomic。 但是,不支持此操作。 在本主题的后面的示例中给出了一种解决方案。您可以修改或比较现有的 QName 类型值。 例如,
/root[1]/e[1] eq expanded-QName("http://nsURI" "myNS")
将元素<>e
的值与 expanded-QName() 函数返回的 QName 进行比较。
示例
本主题针对存储在数据库中各种 xml 类型列中AdventureWorks2022
的 XML 实例提供 XQuery 示例。
A. 替换 QName 类型节点值
此示例说明了如何修改 QName 类型的元素节点的值。 该示例执行以下操作:
创建定义 QName 类型的元素的 XML 架构集合。
使用 XML 架构集合创建具有 xml 类型列的表。
将 XML 实例保存在表中。
使用 xml 数据类型的 modify() 方法修改实例中 QName 类型元素的值。 expanded-QName() 函数用于生成新的 QName 类型值。
-- If XML schema collection (if exists)
-- drop xml schema collection SC
-- go
-- Create XML schema collection
CREATE XML SCHEMA COLLECTION SC AS N'
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="QNameXSD"
xmlns:xqo="QNameXSD" elementFormDefault="qualified">
<element name="Root" type="xqo:rootType" />
<complexType name="rootType">
<sequence minOccurs="1" maxOccurs="1">
<element name="ElemQN" type="xs:QName" />
</sequence>
</complexType>
</schema>'
go
-- Create table.
CREATE TABLE T( XmlCol xml(SC) )
-- Insert sample XML instnace
INSERT INTO T VALUES ('
<Root xmlns="QNameXSD" xmlns:ns="https://myURI">
<ElemQN>ns:someName</ElemQN>
</Root>')
go
-- Verify the insertion
SELECT * from T
go
-- Result
<Root xmlns="QNameXSD" xmlns:ns="https://myURI">
<ElemQN>ns:someName</ElemQN>
</Root>
在以下查询中,元素 <ElemQN
> 值通过使用 xml 数据类型的 modify() 方法和 XML DML 的替换值进行替换,如下所示。
-- the value.
UPDATE T
SET XmlCol.modify('
declare default element namespace "QNameXSD";
replace value of /Root[1]/ElemQN
with expanded-QName("https://myURI", "myLocalName") ')
go
-- Verify the result
SELECT * from T
go
结果如下: 请注意,QName 类型的元素 <ElemQN
> 现在有一个新值:
<Root xmlns="QNameXSD" xmlns:ns="urn">
<ElemQN xmlns:p1="https://myURI">p1:myLocalName</ElemQN>
</Root>
以下语句删除了用于示例的对象。
-- Cleanup
DROP TABLE T
go
drop xml schema collection SC
go
B. 处理使用 expanded-QName() 函数时的限制。
扩展 QName 函数不能用于 XML 构造。 下面的示例对此进行了演示。 为了消除此限制,该示例首先插入一个节点,然后修改此节点。
-- if exists drop the table T
--drop table T
-- go
-- Create XML schema collection
-- DROP XML SCHEMA COLLECTION SC
-- go
CREATE XML SCHEMA COLLECTION SC AS '
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="root" type="QName" nillable="true"/>
</schema>'
go
-- Create table T with a typed xml column (using the XML schema collection)
CREATE TABLE T (xmlCol XML(SC))
go
-- Insert an XML instance.
insert into T values ('<root xmlns:a="https://someURI">a:b</root>')
go
-- Verify
SELECT *
FROM T
以下尝试添加另一个 <root
> 元素,但失败,因为 XML 构造中不支持 expanded-QName() 函数。
update T SET xmlCol.modify('
insert <root>{expanded-QName("http://ns","someLocalName")}</root> as last into / ')
go
解决方法是先插入具有元素值的 <root
> 实例,然后对其进行修改。 在此示例中,插入元素时 <root
> 使用 nil 初始值。 此示例中的 XML 架构集合允许元素 <root
> 的 nil 值。
update T SET xmlCol.modify('
insert <root xsi:nil="true"/> as last into / ')
go
-- now replace the nil value with another QName.
update T SET xmlCol.modify('
replace value of /root[last()] with expanded-QName("http://ns","someLocalName") ')
go
-- verify
SELECT * FROM T
go
-- result
<root>b</root>
<root xmlns:a="https://someURI">a:b</root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p1="http://ns">p1:someLocalName</root>
可以比较 QName 值,如以下查询所示。 查询仅<root
>返回其值与 expanded-QName() 函数返回的 QName 类型值匹配的元素。
SELECT xmlCol.query('
for $i in /root
return
if ($i eq expanded-QName("http://ns","someLocalName") ) then
$i
else
()')
FROM T
实现限制
存在一个限制: expanded-QName() 函数接受空序列作为第二个参数,并在第二个参数不正确时返回空序列,而不是引发运行时错误。