电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

当行与列不能满足需要时


发布日期:2020/3/3
 

使用原生XML(native XML)特性处理不断变化的数据结构

在处理不完全符合关系模型要求的数据或者应用程序必须处理随时间而改变的数据结构时你会怎么做呢?

在本专栏中我将阐明我是如何使用Oracle XML DB的特性来创建一个原型系统的它无需重新编码便能适应新的及改变了的数据结构我还将介绍Oracle的DevTrends网站上的工作示例代码

Oracle XML DB是Oraclei第二版(或更高版)的一组特性它为存储定位和查询XML文档提供了原生支持

应用程序要求

该原型系统将存储并转发政府机构所使用的管理文档(表格状态报告简报等)很高兴这些文档将用XML进行编码但仍存在着一系列难以应对的需求

这些文档的数量类型及内容经常改变

该系统必须同时处理新旧两种文档类型

这些文档有时含有多信息文本(rich text)包括HTML标记

数据是在多个不同位置输入的所以我需要信息域帮助解决数据分布问题

将来系统迟早要支持数字签名

设计要点

即使该系统处理的文档类型会随时间变化我仍然希望能够在存储XML文档时对它们进行验证因此每一种文档类型都需要对定义它的相应XML模式进行注册

使用Oraclei XML DB可以将XML文档分解成关系对象(结构化存储)或者只是将这些文档整个存储为CLOB(非结构化存储)两种方法都利用了原生的XMLType服务器类型从而支持XPath表达式与访问方法

因为该系统必须能够适应新的文档类型而不需改变代码所以文档将存储为CLOB

但只存储XML文档自身是不够的处理文档验证的代码库以及系统的持久性同步和管理取决于某些其他数据元素如全局主关键字日期/时间标记最初位置及正在处理的文档类型这些元素即文档属性必须与在不同位置间发送的XML文档共存所以需要一个属性模式来包含它们

有两种方法可以将XML文档同文档属性关联起来一种是简单地将文档属性元素包含在各个文档模式之中这种方法提供了一种相当扁平的结构它使XPath表达式较短但我却不能处理别人创建的模式另一种方法是将XML文档包装在另一个含有所需属性的XML文档中这种方法需要分别验证包装文档和内容文档但它会提供所需要的灵活性

创建XML模式

我的工作将从创建既能表示包装文档又能表示内容文档的XML模式开始

首先从包装文档开始创建一个XML模式它包含所需的全部文档属性和一个用于内容文档的占位符(利用任一元素类型)所有的文档属性都根据属性元素进行分组我可以用KeyName元素为文档命名以便检索Schema和Element元素指示Content元素中所包含的文档类型

通过Oraclei XML DB可以使用一组特定的模式注释对设置内部存储的方式进行定制我可以指定每个元素的存储类型为所创建的表和类型提供数据库名

在这样的情况下我想混合使用结构化的XML文档存储与非结构化的XML文档存储将内容存储为原生XML将文档属性存储为对象关系类型我将为DOCUMENTS设定defTable属性并给出各Properties元素的SQLName值对于Content元素我打算将存储类型设为CLOB它表示非结构化的XML存储当此模式向数据库注册时XML DB将依照模式注释创建对象关系类型

接下来为了验证置于Content元素中的文档的各个类型还需要为各个文档类型准备一个XML模式

我想跟蹤该系统所能处理的所有内容类型所以我会创建一个存储程序来注册内容模式该程序会记录内容类型名和TYPES表中的其他细节然后向XML DB注册该模式因为我在上一步中已经为这些文档创建了CLOB存储所以当我使用该程序为内容注册任何一种模式时该程序都会告诉XML DB不要创建任何新表或对象类型

Dbms_xmlschemaregisterSchema(

schemaURL => schema_url

schemaDoc => schema

local => true

genTypes => false

genTables => false)

插入数据

现在我将插入一个新文档为了更轻松我要创建一个存储程序它将)检查文档内容是否已注册)验证文档)用一般XML包装文件包装文档并填充属性元素)将文档插入数据库要插入一个新文档只需要像下面这样调用该程序

dtx_docsave(xmltype(

getDocument(incidentxml))

Incident)

getDocument()调用是一个实用程序它基于Oraclei XML数据库开发人员指南附录G中的示例代码它作为一个CLOB从文件系统载入文档第二个参数save()的代表KeyName元素将被用于在文档上建立索引

一个突出的XML DB特性是能够在XML文档存储表上创建基于函数的索引如下所示

CREATE INDEX ix_keyname

ON documents d (dextractValue(

/Document/Properties/KeyName));

检索数据

现在可以对DOCUMENTS表运行基于XPath的查询但如果创建一个XML文档存储的关系视图如清单 所示就能通过标准SQL来访问结构化的存储那么查询就会更容易这样也可以更轻松地查询文档属性

现在可以直接查询该视图以查看文档属性

清单 中的Print_table()过程是Tom Kyte()编写的一个实用程序它可对查询进行纵向格式化 它与本专栏的示例代码一起放在了网上

除了通过SQL调用检索数据外也可以利用内建于该数据库中的Oracle XML DB HTTP协议服务器检索文档如果你的数据库监听程序正在运行你可以在浏览器中输入以下URL以查看插入文档的完整XML

//localhost:/oradb/

DTXDOCS/DOCUMENTS

DTXDOCS是我的数据库用户名我也可以在URL中置入一个XPath查询并指定一个XML样式表它会把XML转换为格式优美的HTML文档

//localhost:/oradb/DTXDOCS/

DOCUMENTS/ROW/Document

[Properties/Subject=Incident]

?transform=/public/dtxdocs/incidentxslt

&contenttype=text/html

示例代码

在DevTrends网站上我已经放置了用于说明本文简述概念的示例代码

其中的说明脚本会告诉你我创建用于应用程序的内部工作的单一代码库以及根据需要向系统注册新文档类型的方法由于我在实际文档中没有使用结构化的存储所以这种方法也可能多少会有助于解决模式发展的问题

Cameron ORourke (camero) 担任Oracle 技术专家已超个

上一篇:一个比较全的simsun.ttf字体设置文件

下一篇:查看文件内容的特殊方法