请考虑一个场景:一个新构建的应用程序需要与不支持本地 XML 的遗留应用程序和存储库集成。XML 文档中存储的信息可能需要放在一个关系表对象中。
假设市场分析的结果需要存储在关系表中,供一个遗留应用程序进行分析。这就要求分解 XML 数据并将它插入关系表中。
pureXML 提供了许多直接操作 XML 数据的工具。如果需要的话,pureXML 也能够执行分解。DB2 9 数据服务器为执行 XML 分解提供了以下内置工具。
1. XDBDECOMPXML 存储过程
可以使用 DB2 9 中的带注释的 XML 模式分解特性将 XML 文档分解到关系表。顾名思义,这个特性在 XML 模式中使用注释作为映射语言,将 XML 文档中的信息映射到关系表。它需要一种 XML 模式,这个 XML 模式文档必须存储在 DB2 XSR 中并表明用于分解。可以通过一个 DB2 存储过程(xdbDecompXML)调用将 XML 文档分解到映射的关系列,也可以使用一个 Command Line Processor(CLP)命令。
关于通过 Visual Studio Add-in 执行 XML 分解的细节,请参考 “Introduction to annotated XML schema decomposition using the DB2 Visual Studio 2005 Add-in”。
注释 XML 模式的另一种方法是使用 DB2 Developer Workbench(DWB)。DWB 可以免费下载,它为创建、编辑、调试、部署和测试 DB2 数据库应用程序提供了一个完整的环境,包括开发存储过程和用户定义的函数。在本文末尾的 参考资料 一节中提供了下载信息。
DWB 的组件之一是用于带注释的 XML 模式分解的 Mapping Editor。可以使用这个简单直观的图形界面在 XML 模式和关系模式之间建立映射。以图形化方式将 XML 元素或属性映射到 DB2 中的关系列,就会自动地在 XML 模式文档中加上注释。保存 XML 模式并在 XSR 中注册之后,就可以将 XML 文档分解到 DB2 数据库中。
对 XML 模式注释和 xdbDecompXML 存储过程的全面讨论超出了本文的范围。要想了解关于带注释的 XML 模式分解的更多信息,包括基于内容的有条件分解或指定在插入前应用的内容转换等高级特性,请参考 DB2 9 XML Guide(参见本文的 参考资料 一节)。要想进一步了解 XML Extender 以及它的分解方法,请参考 Mayank Pradhan 撰写的 developerWorks 文章 “From DAD to Annotated XML Schema Decomposition”。
2. XMLTABLE SQL 表函数
XMLTABLE 是一个 SQL 表函数,它对一个 XML 文档执行 XQuery 表达式并返回一个表。返回的表可以包含任何 SQL 数据类型的列,包括 XML。通过结合使用 XMLTABLE 和 INSERT 语句(这常常被称为 “Insert-from-XMLTABLE” 语句),可以将从 XML 文档获取的值插入关系表中。这样就可以实现与带注释的 XML 模式分解相同的功能。
这提供了一种执行 XML 分解的简单方法,可以将 XML 文档的片段存储在关系表的各个列中。
下面的语句执行一个 XQuery 表达式,并以表的形式返回 DATA 列中的值。每一行显示与特定客户相关联的城市、州、邮政编码和最后购买日期。
清单 19. XMLTABLE 函数
| SELECT X.CITY, X.STATE, X.ZIP, X.LAST_PURCHASE FROM TEAMROOM.XML_CONTENTS, XMLTABLE (XMLNAMESPACES (DEFAULT 'http://www.ibm.com/developerworks'), 'db2-fn:xmlcolumn("XML_CONTENTS.DATA")//customer' COLUMNS "CITY" CHAR(16) PATH './address/city', "STATE" CHAR(16) PATH './address/state', "ZIP" CHAR(6) PATH './address/zip', "LAST_PURCHASE" DATE PATH './last_purchase') as X |
以上 XQuery 的输出类似下面所示:
清单 20. XMLTABLE 输出示例
| Baton Rouge LA 77888 03/10/2007 Baton Rouge LA 14257 01/07/2007 Richmond VA 78045 01/26/2007 Oklahoma City OK 71107 04/13/2007 Tallahassee FL 41720 04/25/2007 Richmond VA 39591 03/25/2007 Richmond VA 36522 03/23/2007 Richmond VA 32230 02/12/2007 Charleston WV 33015 02/12/2007 Columbia SC 72647 01/11/2007 Raleigh NC 11238 04/02/2007 Nashville TN 21245 01/06/2007 Fankfort KY 53793 04/18/2007 Austin TX 35462 03/13/2007 Columbia SC 68359 01/01/2007 Jackson MS 25770 01/20/2007 Little Rock AR 46342 03/10/2007 Tallahassee FL 54306 01/20/2007 Charleston WV 44339 02/20/2007 Frankfort KY 92403 02/27/2007 <etc ........> |
假设定义了具有正确定义的 SQL 类型的 CUSTOMER_INFOS 表,就可以用一个 INSERT 语句封装 SELECT 语句,从而将 XML 市场营销信息中提取出的客户数据(表格式)插入关系表:
清单 21. 将分解的 XML 数据插入关系表
| INSERT INTO TEAMROOM.CUSTOMER_INFOS SELECT X.CITY, X.STATE, X.ZIP, X.LAST_PURCHASE FROM TEAMROOM.XML_CONTENTS, XMLTABLE (XMLNAMESPACES (DEFAULT 'http://www.ibm.com/developerworks'), 'db2-fn:xmlcolumn("XML_CONTENTS.DATA")//customer' COLUMNS "CITY" VARCHAR(16) PATH './address/city', "STATE" CHAR(16) PATH './address/state', "ZIP" CHAR(6) PATH './address/zip', "LAST_PURCHASE" DATE PATH './last_purchase') as X |
另外,Ruby 提供了一个称为 Ruby Electric XML(REXML)的 XML 处理器。可以使用它对 XML 数据进行树解析和流解析。更多细节请参考本文的 参考资料 一节。