作为对xquery语言的扩展,xml dml为xml数据操作提供了更大的灵活性,而不再仅仅是对xml数据进行一些查询操作。通过xml dml,用户可以像操作关系表一样对xml中的节点内容进行插入、更新和删除操作。xml dml需要通过xml数据类型的modify方法进行调用。
1.insert
insert用于将expression1标识的一个或多个节点作为expression2标识的节点的子节点或同级节点插入。语法格式如下:
insert
expression1 (
{as first | as last} into | after | before
expression2
)
expression1和expression2
标识要插入的一个或多个节点。它可以是常量xml实例,也可以是xquery表达式。该表达式可以得出节点、文本节点或一组有序的节点,但它无法解得根节点。如果该表达式得出一个值或一组值,则这些值作为单个文本节点插入,各值之间以空格分隔开。如果将多个节点指定为常量,则这些节点用括号括住,并以逗号分隔开。但无法插入异构序列(如一组元素、属性或值)。如果expression1解得一个空序列,则不会发生插入操作,并且不会返回任何错误。
into
expression1标识的节点作为expression2标识的节点的子节点插入。如果expression2中的节点已有一个或多个子节点,则必须使用as first或as last来指定所需的新节点添加位置。
after
expression1标识的节点作为expression2标识的节点的同级节点直接插入在其后面,after关键字不能用于插入属性。
before
expression1标识的节点作为expression2标识的节点的同级节点直接插入在其前面,before关键字不能用于插入属性。
|||(1)插入元素文档中
在下面的示例中,首先将xml文档分配给xml类型的变量。然后使用几个insert xml dml语句说明如何将元素节点插入文档中。注意在示例中为各种路径表达式都指定了“[1]”,以要求每次只返回单个目标,这样就确保了只有单个目标节点。每次插入后,select语句都会显示结果。最终执行结果如图1所示。
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
</item>
</root>'
select @mydoc
-- 插入item的第1个子节点,此时不需要指定as first或as last
set @mydoc.modify('
insert <author>张洪举</author>
into (/root/item)[1]')
select @mydoc
-- 插入item的第2个子节点,as first指定插入到同级子节点的前面
set @mydoc.modify('
insert <title>sql server 2005开发宝典</title>
as first into (/root/item)[1]')
select @mydoc
-- 插入第2个item节点
set @mydoc.modify('
insert <item id="2"></item>
into (/root)[1]')
select @mydoc
-- 向第2个item中插入第1个子节点
set @mydoc.modify('
insert <title>sql server 2005的新增功能</title>
as first into (/root/item)[2]')
select @mydoc
go
图1 向xml中插入节点
|||商业源码热门下载www.html.org.cn
(2)插入多个元素到文档中
在下面的示例中,将title和author元素插入到了item节点中。元素之间使用逗号分隔,并包含在括号中。
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
</item>
</root>'
select @mydoc
set @mydoc.modify('
insert (
<title>sql server 2005开发宝典</title>,
<author>张洪举</author>
)
into (/root/item)[1]');
select @mydoc
go
(3)插入属性到文档中
在下面的示例中,向xml文档中插入了多个属性。每次插入属性后,select语句都会显示结果,最终执行结果如图2所示。
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
</root>'
select @mydoc
set @mydoc.modify('
insert attribute shipto {"广州"}
into (/root/item[@id=1])[1]');
select @mydoc
-- 通过一个sql变量指定要插入属性shipdate的值
declare @shipdate char(11)
set @shipdate='2006-01-23z'
set @mydoc.modify('
insert attribute shipdate {sql:variable("@shipdate") cast as xs:date ?}
into (/root/item[@id=1])[1]') ;
select @mydoc
-- 插入多个属性,属性之间使用逗号分隔,并包含在括号内
set @mydoc.modify('
insert (
attribute postcode {"253020" },
attribute weight {"1.5"}
)
into (/root/item[@id=1])[1]');
select @mydoc
go
|||图2插入属性到xml中
(4)插入注释节点
在下面的示例中,将注释节点插入到id为2的item节点中title元素的后面。
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<author>卢桂章</author>
</item>
</root>'
set @mydoc.modify('
insert <!-- 注释 -->
after (/root/item[@id=2]/title)[1]');
select @mydoc
go
插入注释后xml的内容如下:
<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<!-- 注释 -->
<author>卢桂章</author>
</item>
</root>
(5)使用cdata部分插入数据
当插入的文本中包含有xml无效字符(如“<”或“>”)时,可以使用cdata部分插入数据。参考下面的示例:
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<author>卢桂章</author>
</item>
</root>'
set @mydoc.modify('
insert <desc><![cdata[ <送货方式>上门<价款>未收]]></desc>
into (/root/item[@id=2])[1] ') ;
select @mydoc
go
|||被插入部分中的xml无效字符,会被转换成实体,如“<”保存为<。下面的插入cdata部分后xml文档的内容:
<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<author>卢桂章</author>
<desc> <送货方式>上门<价款>未收</desc>
</item>
</root>
(6)插入文本节点
要将文件插入到xml中,需要使用text函数构造文本,参考下面的示例:
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
</root>'
set @mydoc.modify('
insert text{"订单列表"}
as first into (/root)[1]');
select @mydoc
go
得到的xml结果如下:
<root>订单列表<item id="1"><title>ajax实战</title><author>张洪举</author></item></root>
(7)将节点插入类型化的xml列中
在下面的示例中,首先创建了一个架构集合,并建立了一个使用该架构集合的表。在使用transact-sql insert语句向表中插入一个符合架构约束的xml后,再使用xml dml insert向该xml中插入一个item节点。
|||-- 创建xml架构集合
create xml schema collection myschemas
as
n'<?xml version = "1.0"?>
<xsd:schema targetnamespace="http://schemas.mybook.com/customerschemas"
xmlns:xsd="http://www.w3.org/2001/xmlschema">
<xsd:element name="customer">
<xsd:complextype>
<xsd:sequence>
<xsd:element maxoccurs="unbounded" name="item">
<xsd:complextype>
<xsd:sequence>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="address" type="xsd:string"/>
<xsd:element name="phone" type="xsd:string"/>
<xsd:element name="contact" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int"/>
</xsd:complextype>
</xsd:element>
</xsd:sequence>
</xsd:complextype>
</xsd:element>
</xsd:schema>';
go
-- 创建包含xml数据类型列的表
create table mycustomer
(customerid int identity primary key,
customeritem xml(myschemas));
go
-- 向表中插入xml,该xml应当符合http://schemas.mybook.com/customerschemas命名空间架构的定义
insert into mycustomer
values
(n'<c:customer xmlns:c="http://schemas.mybook.com/customerschemas">
<item id="1">
<customername>北方书城</customername>
<address>北京市海淀区知春路22号</address>
<phone>2222222</phone>
<contact>刘先生</contact>
</item>
</c:customer>');
-- 使用xml dml insert插入另一个item节点到xml中
update mycustomer
set customeritem.modify('
declare namespace cs="http://schemas.mybook.com/customerschemas";
insert (<item id="2">
<customername>东图大厦</customername>
<address>长春市朝阳大街99号</address>
<phone>1111111</phone>
<contact>孙小姐</contact>
</item>)
into (/cs:customer)[1] ')
where customerid=1;
select customeritem
from mycustomer;
go
|||执行上面的select查询后,可以看到customeritem中的xml内容,如下所示:
<c:customer xmlns:c="http://schemas.mybook.com/customerschemas">
<item id="1">
<customername>北方书城</customername>
<address>北京市海淀区知春路22号</address>
<phone>2222222</phone>
<contact>刘先生</contact>
</item>
<item id="2">
<customername>东图大厦</customername>
<address>长春市朝阳大街99号</address>
<phone>1111111</phone>
<contact>孙小姐</contact>
</item>
</c:customer>
2.delete
delete用于删除xml实例的节点。其语法格式如下:
delete expression
expression是要删除的节点的xquery表达式。删除该表达式选择的所有节点,以及所选节点中的所有节点或值。表达式不能是根(/)节点。如果表达式返回空序列,则不进行删除,不返回错误。
下面的示例演示了从非类型化的xml变量中删除指令、注释、属性、元素和节点的方法。在每次删除后都会显示xml,结果如图3所示。
declare @mydoc xml
set @mydoc = '<?instructions for=thewc.exe ?>
<root>
<!-- 这里是注释 -->
<item id="1" shipto="广州">这里是文本
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<author>卢桂章</author>
</item>
</root>'
select @mydoc
-- 删除注释
set @mydoc.modify('
delete /root/comment()
')
select @mydoc
-- 删除所有指令
set @mydoc.modify('
delete //processing-instruction()
')
select @mydoc
-- 删除id为1的item中的文本节点
set @mydoc.modify('
delete /root/item[@id=1]/text()
')
select @mydoc
-- 删除一个属性
set @mydoc.modify('
delete /root/item[@id=1]/@shipto
')
select @mydoc
-- 删除一个元素
set @mydoc.modify('
delete /root/item[@id=2]/author
')
select @mydoc
-- 删除id为2的item节点
set @mydoc.modify('
delete /root/item[@id=2]
')
select @mydoc
go
|||图3从非类型化xml变量中删除注释、指令、属性、元素和节点
下面的语句演示从类型化xml中删除节点的方法,其中的mycustomer是前面在“将节点插入类型化的xml列中”部分中创建的。
update mycustomer
set customeritem.modify('
declare namespace cs="http://schemas.mybook.com/customerschemas";
delete /cs:customer/item[@id=2]
');
select customeritem from mycustomer;
go
3.replace
replace用于更新文档中的值。其语法格式如下:
replace value of
expression1
with
expression2
expression1
标识其值要更新的节点。它必须仅标识一个单个节点。如果xml已类型化,则节点的类型必须是具有简单类型内容(列表或原子类型)的单个元素、文本节点或属性节点,不能是联合类型、复杂类型、处理指令、文档节点或注释节点。否则,将返回错误。
expression2
标识节点的新值。在修改类型化的xml实例中,expression2与expression1必须是相同类型。
下面的示例演示了更新xml中元素的文本和属性值的方法。每次更改时,都会显示xml,如图4所示。
declare @mydoc xml
set @mydoc = '<root>
<item id="1">
<title>ajax实战</title>
<author>张洪举</author>
</item>
<item id="2">
<title>asp.net实战</title>
<author>卢桂章</author>
</item>
</root>'
select @mydoc
-- 更新id为1的item中的title元素的文本
set @mydoc.modify('
replace value of (/root/item[@id=1]/title/text())[1]
with "ajax实战攻略"
')
select @mydoc
-- 更新属性值
set @mydoc.modify('
replace value of (/root/item[@id=2]/@id)[1]
with "3"
')
select @mydoc
图4 更改xml中元素的文本和属性值
新闻热点
疑难解答