OPENXML

 

OPENXML 通过 XML 文档提供行集视图。由于OPENXML 是行集提供程序,因此可在会出现行集提供程序(如表、视图或 OPENROWSET 函数)的 Transact-SQL 语句中使用 OPENXML。

语法

OPENXML(idoc int [in],rowpattern nvarchar[in],[flags byte[in]])
[WITH (SchemaDeclaration | TableName)]

参数

idoc

是 XML 文档的内部表式法的文档句柄。通过调用 sp_xml_preparedocument 创建 XML 文档的内部表式法。

rowpattern

是 XPath 模式,用来标识要作为行处理的节点(这些节点在 XML 文档中,该文档的句柄由 idoc 参数传递)。

flags

表示应在 XML 数据和关系行集间使用映射以及应如何填充溢出列。flag 为可选输入参数,可以是下列值之一。

字节值
描述
0默认为以特性为中心的映射。
1使用以特性为中心的映射。
在某些情况下,可以将它与 XML_ELEMENTS 组合使用。使用时首先应用以特性为中心的映射,然后对于所有仍未处理的列应用以元素为中心的映射。
2使用以元素为中心的映射。
在某些情况下,可以将它与 XML_ATTRIBUTES 组合使用。使用时先应用以特性为中心的映射,然后对于所有仍未处理的列应用以元素为中心的映射。
8可与 XML_ATTRIBUTES 或 XML_ELEMENTS 组合使用(逻辑 OR)。
在检索的上下文中,该标志指明不应将已消耗的数据复制到溢出属性 @mp:xmltext

SchemaDeclaration

是窗体的架构定义:
ColName ColType [ColPattern | MetaProperty][, ColName ColType [ColPattern | MetaProperty]...]

ColName
是行集中的列名。
ColType
是行集中列的 SQL 数据类型。如果列类型不同于特性的基础 XML 数据类型,那么将发生类型压制。如果列的类型是 TIMESTAMP,则当从 OPENXML 行集中进行选择时,将忽略 XML 文档中现有的值并返回自动填充值。
ColPattern
是可选的通用 XPath 模式,它说明应如何将 XML 节点映射到列。如果没有指定 ColPattern,那么发生默认的映射(由 flags 指定的以特性为中心或以元素为中心的映射)。

指定为 ColPattern 的 XPath 模式用于指定特殊的映射性质(如果发生以特性为中心和以元素为中心的映射),这些特殊的映射性质可以重写或增强由标志所指定的默认映射。

指定为 ColPattern 的通用 XPath 模式也支持元属性。

MetaProperty
是由 OPENXML 提供的元属性之一。如果指定元属性,则该列包含元属性提供的信息。这些元属性使您得以析取 XML 节点的信息(如相对位置、命名空间信息),以提供比文本化表示法更详细的信息。

TableName

如果具有期望架构的表已经存在且不要求列模式,则为给定的表名(而不是 SchemaDeclaration)。

通过使用 SchemaDeclaration 或者指定一个现有的 TableNameWITH 子句提供一种行集格式(根据需要还提供其它映射信息)。如果没有指定可选的 WITH 子句,那么以 edge table 格式返回结果。边缘表在单个表中表示 XML 文档的细密结构(例如,元素/特性名、文档层次结构、命名空间、PI 等)。

下表描述边缘表的结构。

列名数据类型描述
idbigint是文档节点的唯一 ID。

根元素的 ID 值为 0。保留负 ID 值。

parentidbigint标识节点的父节点。此 ID 所标识的父节点不一定是父元素,而是取决于此 ID 所标识节点的子节点的 NodeType。例如,如果节点是文本节点,则其父节点可能是特性节点。

如果节点位于 XML 文档的顶层,则其 ParentID 为 NULL。

nodetypeint标识节点类型。是对应于 XML DOM 节点类型编号的整数(有关节点信息,请参见 DOM)。

三种节点类型是:

1 = 元素节点
2 = 特性节点
3 = 文本节点

localnamenvarchar给出元素或特性的本地名称。如果 DOM 对象没有名称则为 NULL。
prefixnvarchar是节点名称的命名空间前缀。
namespaceurinvarchar是节点的命名空间 URI。如果值是 NULL,则命名空间不存在。
datatypenvarchar是元素或特性行的实际数据类型,否则是 NULL。从内嵌 DTD 中或从内嵌架构中推断数据类型。
prevbigint是前一个兄弟元素的 XML ID。如果前面没有兄弟元素则为 NULL。
textntext包含文本格式的特性值或元素内容(如果边缘表项不需要值则为 NULL)。

示例
A.使用带有 OPENXML 的 SELECT 语句。

下面的示例使用 sp_xml_preparedocument 创建 XML 图像的内部表示。然后对 XML 文档的内部表示法执行使用 OPENXML 行集提供程序的 SELECT 语句。

flag 值设置为 1,表示以特性为中心的映射。因此,XML 特性映射到行集中的列。指定为 /ROOT/Customersrowpattern 标识要处理的 <Customers> 节点。

没有指定可选的 colpattern(列模式),因为列名和 XML 特性名称匹配。

OPENXML 行集提供程序创建了一个双列行集(CustomerID ContactName),SELECT 语句从该行集中检索必要的列(在本例中检索所有的列)。

DECLARE @idoc 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>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/ROOT/Customer',1)
            WITH (CustomerID  varchar(10),
                  ContactName varchar(20))

下面是结果集:

CustomerID ContactName          
---------- -------------------- 
VINET      Paul Henriot
LILAS      Carlos Gonzlez

如果将 flags 设置为 2(表示以元素为中心的映射)并执行相同的 SELECT 语句,由于 <Customers> 元素没有任何子元素,则对于 XML 文档中两个 Customer 的 CustomerIDContactName 的值都作为 NULL 返回。

下面是结果集:

CustomerID ContactName
---------- -----------
NULL       NULL
NULL       NULL
B. 为列和 XML 特性之间的映射指定 ColPattern

下面的查询从 XML 文档返回客户 ID、订单日期、产品 ID 和数量等特性。rowpattern 标识 <OrderDetail> 元素。ProductIDQuantity 是 <OrderDetails> 元素的特性。而 CustomerIDOrderDate 是父元素 (<Orders>) 的特性。

指定可选的 ColPattern,表示:

  • 行集中的 OrderIDCustomerIDOrderDate 列映射到 XML 文档中 rowpattern 所标识节点的父节点的特性。

  • 行集中的 ProdID 列映射到 ProductID 特性,而行集中的 Qty 列映射到 rowpattern 所标识节点的 Quantity 特性。

尽管以元素为中心的映射由 flag 参数指定,但 ColPattern 中指定的映射重写该映射。

declare @idoc 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>'
--Create an internal representation of the XML document.
exec sp_xml_preparedocument @idoc OUTPUT, @doc
-- SELECT stmt using OPENXML rowset provider
SELECT *
FROM   OPENXML (@idoc, '/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
C. 获得边缘表格式的结果

在下例中,在 OPENXML 语句中未指定 WITH 子句。因此,OPENXML 所生成的行集具有边缘表格式。SELECT 语句返回边缘表中的所有列。

下例中的示例 XML 文档由 <Customer>、<Order> 和 <Order_0020_Details> 元素组成。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中

  • rowpattern (/ROOT/Customer) 标识要处理的 <Customer> 节点。

  • 未提供 WITH 子句。因此 OPENXML 以边缘表格式返回行集。

最后 SELECT 语句检索边缘表中的所有列。

declare @idoc int
declare @doc varchar(1000)
set @doc ='
<ROOT>
<Customers CustomerID="VINET" ContactName="Paul Henriot">
   <Orders CustomerID="VINET" EmployeeID="5" OrderDate=
           "1996-07-04T00:00:00">
      <Order_x0020_Details OrderID="10248" ProductID="11" Quantity="12"/>
      <Order_x0020_Details OrderID="10248" ProductID="42" Quantity="10"/>
   </Orders>
</Customers>
<Customers CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Orders CustomerID="LILAS" EmployeeID="3" OrderDate=
           "1996-08-16T00:00:00">
      <Order_x0020_Details OrderID="10283" ProductID="72" Quantity="3"/>
   </Orders>
</Customers>
</ROOT>'
--Create an internal representation of the XML document.
exec sp_xml_preparedocument @idoc OUTPUT, @doc
-- SELECT statement using OPENXML rowset provider
SELECT    *
FROM       OPENXML (@idoc, '/ROOT/Customers')
EXEC sp_xml_removedocument @idoc

结果作为边缘表返回。

03-28
<think>好的,用户想了解OpenXML的使用教程或开发文档。首先,我需要整理关于OpenXML的基本信息和资源。OpenXML是微软Office文档的开放标准,基于XML,适用于Word、Excel、PPT等。用户提到的html2openxml和插入图片的引用可能需要关联到实际应用场景,比如将HTML转成Word文档或插入图片。 接下来,用户可能需要入门教程和官方文档。我记得微软有官方的OpenXML SDK文档,应该先推荐官方资源。然后是开发工具,比如Visual Studio的OpenXML SDK工具包,以及验证文档有效性的工具。 另外,用户可能对实际开发步骤感兴趣,比如如何创建文档、操作元素、处理图片等。需要分点说明,结构清晰。同时,结合用户提到的html2openxml项目,可以推荐相关的第三方库,比如OpenXML-PowerTools,这些能简化开发流程。 书籍推荐也是重要部分,O'Reilly的《Open XML Developer Guide》应该不错,但得确认是否有中文版。社区资源如Stack Overflow和GitHub上的项目可以提供实际帮助,需要包含进去。 最后,用户可能遇到常见问题,比如文档损坏或性能优化,需要给出解决方案。同时,生成的相关问题要覆盖基础概念、实际应用、工具选择等,帮助用户进一步探索。</think>### OpenXML 使用教程与开发文档指南 #### 一、OpenXML 基础概念 OpenXML 是基于 XML 的开放文件格式标准,用于表示 Word(.docx)、Excel(.xlsx)和 PowerPoint(.pptx)等 Microsoft Office 文档。其核心特点包括: 1. **结构化存储**:文档内容按层级结构存储为 XML 文件,压缩为 ZIP 格式 2. **跨平台支持**:可通过编程方式生成或修改文档,无需依赖 Office 软件[^1] 3. **标准化规范**:2015 年成为 ISO/IEC 29500 国际标准 #### 二、官方开发文档 1. **微软官方文档** - [OpenXML SDK 文档](https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk) - 包含 API 参考、代码示例和架构规范 - 提供 Word/Excel/PPT 的 XML 结构说明 2. **ECMA-376 标准文档** - 第五版下载地址:[ECMA International](https://www.ecma-international.org/publications/standards/Ecma-376.htm) - 包含完整的格式规范定义 #### 三、开发环境配置 ```csharp // 示例:通过 NuGet 安装 OpenXML SDK Install-Package DocumentFormat.OpenXml ``` 1. **开发工具** - Visual Studio(推荐 2019 或更新版本) - OpenXML SDK 2.5 Toolbox:用于反编译 Office 文档XML 2. **文档验证工具** ```bash # 使用 OpenXML 验证工具 OpenXmlValidator.exe MyDocument.docx ``` #### 四、基础开发流程(以 Word 为例) 1. **创建新文档** ```csharp using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; var doc = WordprocessingDocument.Create("demo.docx", WordprocessingDocumentType.Document); var mainPart = doc.AddMainDocumentPart(); mainPart.Document = new Document(new Body(new Paragraph(new Run(new Text("Hello OpenXML"))))); doc.Save(); ``` 2. **插入图片(引用用户提到的资源[^2])** ```csharp ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg); using FileStream stream = new FileStream("logo.jpg", FileMode.Open); imagePart.FeedData(stream); var drawing = new Drawing( new DW.Inline( new DW.Extent { Cx = 952500, Cy = 952500 }, new DW.EffectExtent(), new DW.DocProperties(), new DW.NonVisualGraphicFrameDrawingProperties(), new Graphic( new GraphicData( new Picture( new NonVisualPictureProperties(...), new BlipFill(...), new ShapeProperties(...) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" } ) ) ) ); ``` #### 五、进阶学习资源 1. **书籍推荐** - 《Open XML Developer Guide》(O'Reilly) - 《Professional Office Development with Open XML》 2. **实用工具集** - [OpenXML-PowerTools](https://github.com/OfficeDev/Open-Xml-PowerTools):提供高级文档处理功能 - [Html2OpenXml](https://github.com/onizet/html2openxml):实现 HTML 到 OpenXML 的转换(如用户引用的资源) 3. **在线学习平台** - Microsoft Learn 模块:[处理 Office 文档](https://learn.microsoft.com/zh-cn/training/modules/dotnet-create-open-xml-documents/) - Pluralsight 课程:OpenXML 开发实战 #### 六、常见问题解决方案 1. **文档损坏问题** - 使用 `OpenXmlValidator` 检测格式错误 - 添加正确的命名空间声明: ```xml <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> ``` 2. **性能优化** - 使用 `OpenSettings` 控制内存使用: ```csharp var settings = new OpenSettings { AutoSave = true }; using var doc = WordprocessingDocument.Open(filePath, true, settings); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值