简介
正如 W3C 推荐标准 所指出的,XML 的一些设计目标是针对语言的应用程序开发方面:
- “XML 将会支持各种各样的应用程序。”
- “编写处理 XML 文档的程将会很容易。”
其他目标(比如可读性、序列化和传输)得到了许多关注,但是应用程序开发目标没有得到同样的关注。
本文是本系列的第一篇,本系列从三个层面讨论 XML 对应用程序开发的影响:
第 1 部分讨论在哪些情况下在应用程序开发中使用 XML 可以使应用程序开发过程更简单、成本更低、更可移植和质量更高。在这十年中,XML 编程将使应用程序开发方式发生根本性变化,这种变化甚至可能与面向对象方法在过去十年中的影响相当。 数据挖掘研究院
第 2 部分主要讨论数据库的角色。重点是 DB2 9(原来的代码号是 Viper)和 Viper 2 功能。将了解:
- 新的 XML 存储和查询环境如何操作应用程序层的 XML 数据模型
- 采用新的基于 XML 的应用程序开发体系结构之后,数据库模式如何变得更简单更自然
- 如何按照在应用程序中查询数据的相同方式查询数据库中的 XML 数据
- 最后,如何结合关系数据和 XML 数据,从而同时获得这两个环境的优势。
第 3 部分主要关注客户机,介绍在 Web 浏览器和 Web 服务器中使用的 XML 技术:Ajax、XSLT、SVG、Comet、feed 和 mashup。学习如何在数据库中生成 feed 和 Web 服务,在应用程序层查询和组合它们,然后在客户机浏览器中显示它们。
第四篇文章将所有这些技术结合在一起,并展示一个真实的示例。 数据挖掘实验室
XML 数据模型基本知识 数据挖掘实验室
在传统上,XML 用来定义业务文档的元数据。Document Object Model(DOM)用来在应用程序中操作这些元数据。如果我们查看 DOM,就会看到它为层次化 XML 数据结构提供一个对象接口,可以用 DOM API 操作这个层次结构。换句话说,DOM 可以作为对象包装器操作任何可以用 XML 表示的数据结构。 数据挖掘实验室
在 XML 数据模型中,将许多应用程序数据对象定义为 XML。因为 XML 是层次化的,所以很容易以自然的、人可读的格式捕捉不同数据对象之间的关系。 数据挖掘研究院
注意: 数据挖掘研究院
如果数据已经是 XML 格式的,过程的其余部分就很自然很简单了。如果数据是关系格式,仍然可以使用这种方法,但是需要在关系数据和 XML 数据之间建立双向映射。这个步骤可以使用 SQL/XML 发布和分解函数来实现。大多数关系数据库支持这些函数和其他映射技术。对于在应用程序开发中只使用 XML 作为数据模型的许多开发人员,关系数据到层次化数据(XML)的映射似乎是不必要的。但是作为开发人员,在将关系映射到数据对象时,我们总是这么做。使用 XML 数据模型的优点可能足以促使许多开发人员考虑在应用程序开发中使用 XML,即使在他们的业务模型中并不需要 XML 数据。 数据挖掘研究院
定义了 XML 数据模型之后,可以使用 DOM 解析器在应用程序中实例化 XML 数据模型。为了隔离应用程序代码与用来导航和操作 XML 模型的 DOM API,可以为 DOM 和 XPath 实现创建一个包装器。这个包装器也会使应用程序代码的可移植性更好。 数据挖掘研究院
本文提供了 一个 Java 包装器示例,您可以直接使用它,也可以用它作为模板建立自己的包装器。应用程序的业务逻辑使用包装器 API 直接操作 XML 模型。修改后的 XML 数据可以轻松地序列化,并在不同对象或多层环境(SOA)的不同层之间传递。 数据挖掘研究院
XML 数据模型与数据对象模型 数据挖掘研究院
大多数应用程序由业务对象组成,业务对象操作数据对象的层次结构。数据对象一般是业务数据的简单包装器。它们的主要用途是以受控制的方式向业务对象公开封装的数据。使用对象包装器的另一个好处是,它们可以以自然的对象层次结构表达关系表中存储的数据,从而捕捉数据之间的关系。编程工作的一个主要部分就是为应用程序业务数据创建这些对象包装器。
因为 XML 本质上维护数据结构之间的关系,所以不需要创建单独的对象层次结构来捕捉各个数据结构之间的关系。另外,XML 已经有一个标准的对象模型,Document Object Model(DOM)。这个模型的实现处理 XML 数据的构造、修改和序列化。通过结合使用 XPath 和 DOM API,很容易在业务应用程序中装载、修改和保存 XML 数据。 数据挖掘研究院
一个真实示例 数据挖掘研究院
为了更好地理解这两个模型之间的差异,我们来看看每个模型如何影响应用程序的设计和实现。
我将使用一个简单的场景演示这两种方式,这个场景要处理客户和订单信息。
数据对象模型
按照数据对象模型方式,首先需要创建包装器对象来封装客户和订单数据,见清单 1、清单 2 和清单 3。
清单 1. 创建客户 数据挖掘研究院
| public class Customer { int customerid; String firstname; String lastname; Items itemspurchased ; Public Customer (int custid, Connection conn) { Statement dbstmt= conn.createStatement(); ResultSet dbResult = dbstmt.executeQuery("select fname, lname from customer_table where customerid=custid"); customerid=custid; SetFirstName(dbResult.getString(1)); SetLastName(dbResult.getString(2)); } public String GetFirstName {return firstname;} public Void SetFirstName (fname) {firstname=fname;} public String GetLastName {return lastname ;} public Void SetLastName (lname) {lastname=lname;} public Items GetItemsList {return itemspurchased; } public SetItemsList (list) { itemspurchased =list;} } |
清单 2. 创建 Items 类 数据挖掘研究院
| public class Items { Hashtable list=new Hashtable(); Public Items(int custid,Connection conn) { Statement dbstmt= conn.createStatement(); ResultSet dbResult = dbstmt.executeQuery("select itemid, description, price, date from purchase_table where customerid=custid") While (dbResult.rs.next ()) { tempitem = new Item(); tempitem.SetID(dbResult. getString(1)); tempitem. SetDescription (dbResult. getString(2)); tempitem. Setprice (dbResult. getFloat(3)); tempitem. SetpurchaseDate (dbResult. getString(4)); Additem (tempitem); } } public void AddItem (item oneitem) {list.put(oneitem.GetID(),oneitem);} public Item GetItem (ItemID) {return list.get(String itemID);} public Hashtable GetItems(){return list;} public Items FindItemByPrice (flaot min, float max) { Items retList=new Items(); for (Enumeration e=list.elements () ; e.hasMoreElements() ; ) { item tmpItem=(item)e.nextElement(); float price= tmpItem .GetPrice(); if(price >= min && price <=max) { retList.AddItem(tmpItem); } } } public Items FindItemByDate (purchaseDate) { } } |
清单 3. 创建 Item 定义
| public class Item { String id; String description; String purchaseDate; Float price; Public void SetID (String ItemID) {id= ItemID;} Public void SetDescription (String desc) { description = desc;} Public void SetpurchaseDate (String pDate) { purchaseDate = pDate ;} Public void Setprice (float pprice { price = pprice ;} Public String GetID (){return id;} Public String GetDescription(){return description;} Public float GetPrice(){return price;} } |
现在可以在应用程序中使用这些数据对象来管理底层数据。
清单 4. 在应用程序中操作数据对象
| Customer customer = new Customer (custid,dbConnection) customer.SetItemList (new Items(custid , dbConnection)) ; Items list=customer.GetItemsList(). FindItemByPrice(15.0,25.50); for (Enumeration e=list.elements () ; e.hasMoreElements() ; ) { System.out.println(((item)e.nextElement()).GetDescription()); } |
在上面的示例中,我们发现数据对象的代码比业务逻辑需要的代码多得多。另外,因为包装器对象隐藏了底层业务数据之间的关系,所以包装器对象 API 必须有良好的文档记录,应用程序开发人员才能了解如何正确地使用它们。 数据挖掘实验室
在数据对象模型中,很容易在对象层次结构之间进行简单的导航,但是必须为每个搜索条件实现高级搜索和导航功能(例如 FindItemByPrice)。
数据挖掘研究院
