使用sp_xml_preparedocument处理XML文档
有时会在存储过程中处理一些XML格式的数据,所以会用到sp_xml_preparedocument,他可以将XML数据进行读取,然后使用 MSXML 分析器 (Msxmlsql.dll) 对其进行分析。我们就可以很容易的在存储过程中得到XML中我们想要的数据。下面的代码就是使用sp_xml_preparedocument读取XML:
DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
</Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
<Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
<OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
</Order>
</Customer>
</ROOT>' EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
上面只是读取了XML,要想获取XML数据还需要使用OPENXML,代码如下:
SELECT *
FROM openxml(@hdoc,'/ROOT/Customer',1)
WITH (CustomerID VARCHAR(40),ContactName VARCHAR(40))
OPENXML有三个参数:
- 第一个是sp_xml_preparedocument读取是的OUTPUT参数,在本示例中就是@hdoc;
- 第二个是一个XPath表达式,用来获取指定位置的数据;
- 第三个是一个可选项,用来表示获取的方式,有0,1,2,8四种取值,详细解释请看
FROM后面的WITH也是可选的,用来指定获取哪些数据字段,上面代码中只取了CustomerID和ContactName。上面的查询结果如下: CustomerID ContactName ---------------------------------------- ---------------------------------------- VINET Paul Henriot LILAS Carlos Gonzlez 如果不指定WITH子句,查询出来的是一个默认的表结构,如下:

表格列的解释说明:
| 列名 | 数据类型 | 说明 |
|---|---|---|
| id | bigint | 文档节点的唯一 ID。 根元素的 ID 值为 0。保留负 ID 值。 |
| parentid | bigint | 标识节点的父节点。此 ID 标识的父节点不一定是父元素。具体情况取决于此 ID 所标识节点的子节点的节点类型。例如,如果节点为文本节点,则其父节点可能是一个属性节点。 如果节点位于 XML 文档的顶层,则其 ParentID 为 NULL。 |
| 节点类型 | int | 标识节点类型,是对应于 XML 对象模型 (DOM) 节点类型编号的一个整数。 下列值是可以显示在此列中以指明节点类型的值: 1 = 元素节点 2 = 属性节点 3 = 文本节点 4 = CDATA 部分节点 5 = 实体引用节点 6 = 实体节点 7 = 处理指令节点 8 = 注释节点 9 = 文档节点10 = 文档类型节点 11 = 文档片段节点 12 = 表示法节点 有关详细信息,请参阅 Microsoft XML (MSXML) SDK 中的“节点类型属性”主题。 |
| localname | nvarchar(max) | 提供元素或属性的本地名称。如果 DOM 对象没有名称,则为 NULL。 |
| prefix | nvarchar(max) | 节点名称的命名空间前缀。 |
| namespaceuri | nvarchar(max) | 节点的命名空间 URI。如果值是 NULL,则命名空间不存在。 |
| datatype | nvarchar(max) | 元素或属性行的实际数据类型,否则是 NULL。数据类型是从内联 DTD 中或从内联架构中推断得出。 |
| prev | bigint | 前一个同级元素的 XML ID。如果前面没有同级元素,则为 NULL。 |
| text | ntext | 包含文本形式的属性值或元素内容。如果边缘表项不需要值则为 NULL。 |
在WITH子句中,我们还可以通过设置来获取父级元素的属性值:
DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order OrderID="10248" CustomerID="VINET" EmployeeID="5"
OrderDate="1996-07-04T00:00:00">
<OrderDetail ProductID="11" Quantity="12"/>
<OrderDetail ProductID="42" Quantity="10"/>
</Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
<Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"
OrderDate="1996-08-16T00:00:00">
<OrderDetail ProductID="72" Quantity="3"/>
</Order>
</Customer>
</ROOT>' EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
SELECT *
FROM OPENXML (@hdoc, '/ROOT/Customer/Order/OrderDetail',2)
WITH (OrderID int '../@OrderID',
CustomerID varchar(10) '../@CustomerID',
OrderDate datetime '../@OrderDate',
ProdID int '@ProductID',
Qty int '@Quantity')
查询的结果为: OrderID CustomerID OrderDate ProdID Qty ----------- ---------- ----------------------- ----------- ----------- 10248 VINET 1996-07-04 00:00:00.000 11 12 10248 VINET 1996-07-04 00:00:00.000 42 10 10283 LILAS 1996-08-16 00:00:00.000 72 3 有时候XML中的数据并不是以属性的方式存在,而是直接放在节点中,如下:
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<EmployeeID>5</EmployeeID>
<OrderDate>1996-07-04T00:00:00</OrderDate>
</Order>
</Customer>
</ROOT>'
此时要获Order节点下的各项的值,可以用下面方法:
DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<EmployeeID>5</EmployeeID>
<OrderDate>1996-07-04T00:00:00</OrderDate>
</Order>
</Customer>
</ROOT>' EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
SELECT *
FROM OPENXML (@hdoc, '/ROOT/Customer/Order',1)
WITH (OrderID int 'OrderID',
CustomerID varchar(10) 'CustomerID',
EmployeeID int 'EmployeeID',
OrderDate datetime 'OrderDate')
查询结果如下: OrderID CustomerID EmployeeID OrderDate ----------- ---------- ----------- ----------------------- 10248 VINET 5 1996-07-04 00:00:00.000 可以看出是取属性值还是取节点的文本的值区别在于WITH子句的第三个参数是否有@符号

出处: http://oec2003.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则 保留追究法律责任的权利。
使用sp_xml_preparedocument处理XML文档的更多相关文章
- sp_xml_preparedocument _使用 处理XML文档
有时会在存储过程中处理一些XML格式的数据,所以会用到sp_xml_preparedocument,他可以将XML数据进行读取,然后使用 MSXML 分析器 (Msxmlsql.dll) 对其进行 ...
- C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素”
Q: 在反序列化 Xml 字符串为 Xml 对象时,抛出如下异常. 即在 XML文档(0, 0)中有一个错误:缺少根元素. A: 首先看下代码: StringBuilder sb = new Stri ...
- 【.net 深呼吸】使用二进制格式来压缩XML文档
在相当多的情况下,咱们写入XML文件默认是使用文本格式来写入的,如果XML内容是通过网络传输,或者希望节省空间,特别是对于XML文档较大的情况,是得考虑尽可能地压缩XML文件的大小. XmlDicti ...
- 【Win 10应用开发】把文件嵌入到XML文档
把文件内容嵌入(或存入)到XML文档中,相信很多朋友会想到把字节数组转化为Base64字符串,再作为XML文档的节点.不过,有人会说了,转化后的base64字符串中含有像“+”这样的符号,写入到XML ...
- 用ORM的思想操作XML文档,一个对象就搞定不要太简单。滚蛋吧!XmlDocument、XmlNode、Xml***……
大家有没有这样的感受,一涉及XML文档操作就得百度一遍.是不是非!常!烦!.各种类型,各种方法,更别提为了找到一个节点多费劲.本来想写个XML操作的工具方法,写了两行一想既然XML文档是有规律的,如果 ...
- 【Win10 应用开发】自适应Toast通知的XML文档结构
老规矩,在开始之前老周先讲个故事. 话说公元2015年7月20日,VS 2015发布.于是,肯定有人会问老周了,C#6有啥新特性,我学不来啊.学不来的话你应该检讨.老周比较保守地计算一下,学会C# 6 ...
- XML文档操作集锦(C#篇)
在JSON没流行起来的时候xml一直作为程序存储配置信息的主流介质:特别是小型数据表方面还是不错的选择,所以经常涉及到的操作无非也就是增删改查,这篇博客主要是对这些对比较常用的操作做了个简单的总结 文 ...
- XmlReader和XElement组合之读取大型xml文档
简介 在.NET framework 中存在大量操作xml数据的类库和api,但在.NET framework 3.5后我们的首选一般就是linq to xml. linq to xml操作xml数据 ...
- Java获取XML节点总结之读取XML文档节点
dom4j是Java的XML API,用来读写XML文件的.目前有很多场景中使用dom4j来读写xml的.要使用dom4j开发,需要下载导入dom4j相应的jar文件.官网下载:http://www. ...
随机推荐
- Gravatar注册
今天在学习falsk时需要用到头像扩展,需要使用gravatar到网上查了查好像没有被墙,就试着用qq邮箱注册了一个账号,结果等了好长时间也没有等到激活邮箱,就百度了一下发现了一个技巧,原来这封邮件被 ...
- 修改Excel2013默认模版(启动模版和新建Sheet模版)
1. C:\Windows\ShellNew\EXCEL12.XLSX 设置好格式后另存为, 然后复制过来覆盖掉,如果覆盖不了,注意修改所有者权限 2. 新建文件保存为模版文件Sheet.xltx, ...
- Linux下百度云盘报 获取bdstoken失败
在用linux下百度云盘工具(bcloud),登录时,报获取bdstoken失败. 在网上搜了一下,解决办法如下. 找到auth.py文件 locate auth.py |grep bcloud 结果 ...
- 错误 Metadata file 'C:\Common\bin\Debug\Common.dll' could not be found
一个通用方法de类库/总是报这个错误/很明显就是没有成功生成程序集... 但是就是找不到哪里的错误!!!! 如果是代码写错的话,可能会直接提示在哪个文件中哪行代码写错了,然后dll生成不了,但是这个错 ...
- tyvj1102 单词的划分
描述 有一个很长的由小写字母组成字符串.为了便于对这个字符串进行分析,需要将它划分成若干个部分,每个部分称为一个单词.出于减少分析量的目的,我们希望划分出的单词数越少越好.你就是来完成这一划分工作的. ...
- spark streaming 接收 kafka 数据java代码WordCount示例
http://www.cnblogs.com/gaopeng527/p/4959633.html
- iOS开发——高级篇——二维码的生产和读取
一.二维码的生成 从iOS7开始集成了二维码的生成和读取功能此前被广泛使用的zbarsdk目前不支持64位处理器 生成二维码的步骤:导入CoreImage框架通过滤镜CIFilter生成二维码 二维码 ...
- html用户注册界面
html用户注册界面 先上一张简约的界面的效果图 这里是style里面的内容 <style> input[type]{ border: 1px solid darkorange; ba ...
- Windows7 + Ubuntu双系统安装过程记录
本文为在已安装Windows7系统的前提下安装Ubuntu Kylin 14.10系统的过程以及期间出现的各种问题的记录. Ubuntu系统下载 Ubuntu Kylin中文官方网站:http://w ...
- jquery写简单的div切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...