|
XML问题#12:使用Python模块xml2sql和dtd2sql广告 XML问题#12:使用Python模块xml2sql和dtd2sql
格式操纵员,Gnosis Software, Inc. 2001 年 6 月 前面有一篇专栏研究了从 SQL 查询生成 XML 文档。现在,David Mertz 说明将 XML 文档和 DTD 反向转换成
RDBMS 存储格式也同样可能,但它有自己的约束和复杂性集合。Python 公众域利用了这里所讨论的 xml2sql 和 dtd2sql 生成 SQL
语句,以一种一致和可逆的方式创建和填充数据库。这里使用了 7 个代码示例演示了这些技术。 告诫 而且,xml2sql 和 dtd2sql 最适合于包含从面向表信息开始的 XML 文档。对于面向散文和面向线性的 XML 文档的转换,它们则显得苍白无力。在这方面所强加的限制本质上等同于 xml2sql 利用的 xml_objectify 库所强加的限制。不过,这一特殊焦点严格来说算不上是限制:实际上,任何技术 -- 就是定制开发 -- 都无法在 RDBMS 框架中产生非常自然的散文数据和线性数据的表示。各个模型均不相同, xml2sql 和任何实用程序一样只能做到大致良好的地步。 最后,不要指望 xml2sql 特别快或者特别有效;这种实用程序主要是为可移植性和通用性而设计的。因此,不调用任何数据库的库 -- 无论是特定的 RDBMS 还是通过象 ODBC 这样的机制 -- xml2sql 和 dtd2sql 都创建简单的文本 SQL 语句。模块 dtd2sql 生成 CREATE TABLE 语句的列表,而 xml2sql 生成 INSERT INTO 语句的列表。是否将这些语句放入实际的 RDBMS 由用户或程序员决定。这种安排的好处在于,开发人员可以同样好地将这些语句放入任何供应商的 RDBMS。 尝试一下 出于测试目的,我创建了一个简单的测试脚本。出于开发目的,我使用流行的开放源码 RDBMS mySQL。虽然与更复杂的 RDBMS 相比, mySQL 有一些限制,它提供了一个非常好的测试平台。样本 DTD 和 XML 文档属于我所编写的 developerWorks 教程(请参阅参考资料中的集合)。清单 1 中的脚本是 OS/2 命令文件,但在 Windows 下也应该一样有效,在类 Unix 的系统上只需要少许修改。 清单 1. 将 XML 传送到 SQL 所使用的测试脚本 echo drop database test;
> test.sql 清单 1 中脚本的前面几行只是清除并恢复 mySQL 中的 test 数据库。在现实生活中,您不太会 drop 现有的数据库,而只是从表中 INSERT 和 DELETE。我使用 drop 是因为在测试时最好重新开始。 运行 dtd2sql 时,它从 STDIN 或从命令行上给出的文件名中获得 DTD。这个 DTD 可能是 XML 文档的内部子集,如果愿意,它也可以是外部文件。不过,这个工具一次只能从单一源中读取,它当前不处理复杂的多文件 DTD、参数实体或部分覆盖外部定义的内部子集。前面提到过,dtd2sql 只产生一组 CREATE TABLE 语句。 在清单 2 中,可以看到来自 dtd2sql 的一个输出行,然后理解如何将其各个部分拆解(为显示起见添加了一些折行)。 清单 2. 来自 dtd2sql 的样本 CREATE TABLE 语句 CREATE TABLE a ( 某些列名很容易由 a 元素本身的定义解释;对于其它的,则需要加以进一步研究。 清单 3. <a> XML 元素的 DTD 项 <!--A hyperlink to some other resource.--> 每个 CREATE TABLE 语句都包括一个 primary_key 和 seq 列。seq 列有时没什么意义(除了表明缺少属于某些行的顺序性)。用户在命令行上或通过定制应用程序运行这样的 CREATE TABLE 语句将在每个表中创建这些列。href 列直接来自同样命名 XML 的标记属性。PCDATA 和 _XML 列存放的是实际的元素内容(有或没有任何嵌入式字符级标记)。 所示的 CREATE TABLE 语句中最有意思的是几个 foreign_key_* 列。我会在下面考虑这些。 创建关系 很明显,dtd2sql 无法执行数据库分析师所执行的所有背景研究:它有的只是 DTD(也可能是 XML 文档)。在这个基础上,没有一种真正的方法可以确定哪些属性或元素内容是唯一的(如果有的话)。幸好, dtd2sql 可以采取某些商业 RDBMS 的途径,这样就能轻易地避开“天然的”主键。模块能够选择完全人造的主键 -- 在拒绝所有数据表示角色时分解出唯一性需求的那些主键。我不认为这样的模式在数据库设计中能够实际达到比标识适合“现实世界”数据的更常用策略更好的正交性。而且这种方法在为每个表的主键提供完全一致和可预测的名称以及格式方面有着额外的优势。 使用的主键是随机 18 位整数。假设 Python 的 random 模块相当好,冲突的风险也非常小。不过,代码并不能严格保证无冲突(可能在以后的版本中可以)。到目前为止还不错。 下一步是使这些主键可用于 SQL JOIN 目的。要这样做,需要确保当 XML 元素包含子元素时,子元素包含与父代主键相对应的外键。不可否认,达到上述目的最节约的方法是为每个非根的 XML 元素创建一个 foreign_key 列。在那种情况下,查询合成数据库的 SQL 用户需要知道哪些 JOIN 会产生结果(例如通过读取原始 DTD)。 抛开节约,我选择明确性。我为每个可能是与表所对应的 XML 元素父代的元素创建了单独的 foreign_key_* 列。所以在上述 CREATE TABLE 示例中,dtd2sql 标识了在清单 4 中显示的 DTD 元素定义。 清单 4. 可能是 <a> 的父代的元素 <!ELEMENT p
(#PCDATA | code | img | br | i | b | a)* > dtd2sql 明确方法的一个好处是,所创建的表结构固有地在 DTD 中包含大部分信息(但并非全部,因为量词并不因此而有分别)。 走些弯路 事实是 xml2sql 做的非常少。其核心(walkNodes() 函数)代码连 50 行都没有。而且,即使这几行文档都编制得非常详细,无法通过编程技巧来达到简明性。当然, xml2sql 所执行的大部分任务实际上是由 xml_objectify 完成的。xml2sql 的第一步是使用 xml_objectify 创建一个“Python 化”的对象。然后,要遍历所有嵌套的属性就很简单了,在进行中输出 INSERT INTO SQL 语句。不过,旧版本 xml_objectify 的用户需要获取最新的版本,因为 XML 元素命名方式的细小更改造成了一路“破坏”。 一旦运行了 xml2sql,您会得到一束 SQL 语句作为回报。这组语句按照正常的 STDOUT 行为可以被重定向和导向管道,使得 xml2sql 与 RDBMS 命令行工具的结合非常直截了当。如果希望使用 xml2sql 作为支持模块,可以获得以 Python 列表获取该组 SQL 语句(可能对于和某些数据库模块一起使用很方便)。产生的典型语句看起来如清单 5 中的示例所示(为显示起见进行了折行)。 清单 5. 产生的典型语句 INSERT INTO p 可以从清单 5 中 INSERT INTO 的形式看出,对应 DTD 中的 <p> 元素创建了一个表。实际上,我们只是知道该元素出现在 XML 文档中;对照 DTD 确认 XML 文档是需要在这些模块外部处理的作业。但假设 XML 文档是有效的,dtd2sql 可以创建正确的表和列。 还可以在 INSERT INTO 中看到这个特殊的 <p> 标记是嵌套在 <text-column> 元素内部的(需要对某些名称做大改动才能获得有效的 SQL 列名),即,具有 527610371062647168 主键的元素。它也证明了这个 <p> 元素具有某些 PCDATA 内容,它的 seq 列值为零。该列表位的含义是,<p> 元素独立位于其容器中;如果在同一个 <text-column> 中出现多个 <p> 元素,它们就按顺序排列,从 1 开始。 组合起来 清单 6. 从 RDBMS 中选择数据 SELECT "Paragraph", p.seq, p._XML 有必要进行一些解释。JOIN 的构成都一样:foreign_key_X 字段与某些表 X 的 primary_key JOIN 起来。一旦所有 JOIN 都就位后,可以添加 ORDER、GROUP 等等更实质性的条件。在这种情况下,您希望查看其 <title> 是 "About Haskell" 的 <panel> 的所有 paragraph(段落)(<p> 元素)。结果看上去如清单 7 所示。 清单 7. 针对 XML 教程的 SQL 查询 C:\mysql2\bin>mysql -u root -pgnosis test <
haskell.sql 结束语 通过单击本页顶部或底部的讨论来询问问题或对本文加以评论。 本文中讨论的模块可从以下站点下载:http://gnosis.cx/download/dtd2sql.py 和 http://gnosis.cx/download/xml2sql.py。 本文中使用的支持和数据文件的归档可以在以下站点找到:http://gnosis.cx/download/xml_matters_12.zip。 可以在以下站点找到支持模块 通常,Gnosis Software 下载目录包含了我开发的各种软件,大多用于 IBM developerWorks 专栏和文章。通常可以在该目录找到各种版本的特殊软件模块,包括最新最完善的那些以及早期的那些。请查看:http://gnosis.cx/download/。 复习 David Mertz 以前的“XML 话题”专栏: XML 问题 #1 介绍 Python xml_pickle 对象。 XML 问题 #2 描述如何使用 Python 的 xml_objectify。 XML 问题 #3 介绍 DocBook。 XML 问题 #4 继续介绍如何使用 DocBook 构建旧的文档档案。 XML 问题 #5 说明如何通过 XSLT 将 XML 文档转换成 HTML。 XML 问题 #6 比较了几种 XML 编辑器,同时特别着眼于那些适合于文本繁重的文档的工具。 XML 问题 #7 将 DTD 与 XML Schema 进行了权衡,并建议无论 W3C XML Schema 规范有多么成熟,开发者在什么情况下需要坚持使用 DTD。 XML 问题 #8 讨论由计算机科学家所概念化出来的数据模型的抽象理论是如何帮助我们开发特定的多表示数据流的。 XML 话题 #9 讨论了公众域 XML 话题 #10 扩展 David 的“可爱的 Python #15”专栏中介绍的常规全文本索引器来包括特定于 XML 的搜索和索引特性,并讨论索引器如何利用 XML 的分层节点结构。 XML 话题 #11 重温了在本系列第一个专栏中介绍的模块
IBM 的 DB2 Extender 页面提供了 DB2 如何与 XML 一起使用的基本概述,并包括了到有关查询 XML 的详细白皮书(可作为 PDF 文件查看)和到 DB2 Extender 下载的链接。 Solutions 2001 开发人员大会将于 8 月 13 日到 18 日在旧金山召开;可以在 AgendaBuilder 中搜索或浏览超过 230 个会议的描述。有超过二十多个会议主要讨论 XML 和相关技术,包括: Hands-on: Integrating XML with DB2 Hands-on: Voice XML Tools/Building Killer Apps XSL by Example: An Introduction to XML Transformations Parsing and Programming XML Documents using Java Technology 请参与包含 17 个问题的
有关开发习惯的调查以帮助 IBM 改进开发软件应用程序的 XML 工具开发和服务。
如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐 jill.jiang@amteam.org | 021-51096826-112 | 在线联系 |
节能与优化IT 企业CIO过冬良策当前金融危机的影响还在继续漫延,很多企业都在苦寻过冬的良策,在这种情况下,节能与优化技术与产品无疑成为CIO们关注的首要对象,本次选题就是针对节能与优化IT来为CIO们提供过冬的良…… |
|
|