简介
正如 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. 创建客户
publicclassCustomer
...{
intcustomerid;
Stringfirstname;
Stringlastname;
Itemsitemspurchased;
PublicCustomer(intcustid,Connectionconn)
...{
Statementdbstmt=conn.createStatement();
ResultSetdbResult=dbstmt.executeQuery("selectfname,lnamefrom
customer_tablewherecustomerid=custid");
customerid=custid;
SetFirstName(dbResult.getString(1));
SetLastName(dbResult.getString(2));
}
publicStringGetFirstName...{returnfirstname;}
publicVoidSetFirstName(fname)...{firstname=fname;}
publicStringGetLastName...{returnlastname;}
publicVoidSetLastName(lname)...{lastname=lname;}
publicItemsGetItemsList...{returnitemspurchased;}
publicSetItemsList(list)...{itemspurchased=list;}
}
清单 2. 创建 Items 类
publicclassItems
...{
Hashtablelist=newHashtable();
PublicItems(intcustid,Connectionconn)
...{
Statementdbstmt=conn.createStatement();
ResultSetdbResult=dbstmt.executeQuery("selectitemid,description,
price,datefrompurchase_tablewherecustomerid=custid")
While(dbResult.rs.next())
...{
tempitem=newItem();
tempitem.SetID(dbResult.getString(1));
tempitem.SetDescription(dbResult.getString(2));
tempitem.Setprice(dbResult.getFloat(3));
tempitem.SetpurchaseDate(dbResult.getString(4));
Additem(tempitem);
}
}
publicvoidAddItem(itemoneitem)...{list.put(oneitem.GetID(),oneitem);}
publicItemGetItem(ItemID)...{returnlist.get(StringitemID);}
publicHashtableGetItems()...{returnlist;}
publicItemsFindItemByPrice(flaotmin,floatmax)
...{
ItemsretList=newItems();
for(Enumeratione=list.elements();e.hasMoreElements();)
...{
itemtmpItem=(item)e.nextElement();
floatprice=tmpItem.GetPrice();
if(price>=min&&price<=max)
...{
retList.AddItem(tmpItem);
}
}
}
publicItemsFindItemByDate(purchaseDate)...{}
}
清单 3. 创建 Item 定义
publicclassItem
...{
Stringid;
Stringdescription;
StringpurchaseDate;
Floatprice;
PublicvoidSetID(StringItemID)...{id=ItemID;}
PublicvoidSetDescription(Stringdesc)...{description=desc;}
PublicvoidSetpurchaseDate(StringpDate)...{purchaseDate=pDate;}
PublicvoidSetprice(floatpprice...{price=pprice;}
PublicStringGetID()...{returnid;}
PublicStringGetDescription()...{returndescription;}
PublicfloatGetPrice()...{returnprice;}
}
现在可以在应用程序中使用这些数据对象来管理底层数据。
清单 4. 在应用程序中操作数据对象
Customercustomer=newCustomer(custid,dbConnection)
customer.SetItemList(newItems(custid,dbConnection));
Itemslist=customer.GetItemsList().FindItemByPrice(15.0,25.50);
for(Enumeratione=list.elements();e.hasMoreElements();)
...{
System.out.println(((item)e.nextElement()).GetDescription());
}
在上面的示例中,我们发现数据对象的代码比业务逻辑需要的代码多得多。另外,因为包装器对象隐藏了底层业务数据之间的关系,所以包装器对象 API 必须有良好的文档记录,应用程序开发人员才能了解如何正确地使用它们。
在数据对象模型中,很容易在对象层次结构之间进行简单的导航,但是必须为每个搜索条件实现高级搜索和导航功能(例如 FindItemByPrice)。
XML 数据模型
因为包装器的主要用途是封装业务数据,所以可以用 XML 数据模型替换它们。
清单 5. XML 数据模型
<Customercustomerid=""firstname=""lastname="">
<Items>
<ItemID=""description=""purchaseDate=""price=""/>
</Items>
</Customer>
现在,假设数据库中的数据已经存储为 XML 格式:
- 客户数据存储为 <Customer customerid ="" firstname="" lastname="" />
- 商品数据存储为 <Item ID="" description="" purchaseDate="" price="" />
那么,对于任何给定的客户,我们只需获取客户 XML 并在其中插入查询的商品列表。
重写应用程序代码,让它使用 XML 模型保存客户和商品信息。为了创建和操作这个 XML 数据模型的实例,我们将使用 DOM 包装器类 XMLParse(见 下载 一节)。
第一种情况 —— 数据在数据库中存储为 XML 格式
清单 6. 重写应用程序来使用 XML 模型
1.Statementdbstmt=conn.createStatement();
2.ResultSetdbResult=dbstmt.executeQuery("selectcustXMLfrom
customer_tablewherecustomerid=custid");
3.XMLParsecustomerXML=newXMLParse(dbResult.getString(1));
4.customerXML.appendNode("/Customer",customerXML.createNode("<Items/>"))
5.dbResult=dbstmt.executeQuery("selectitemXMLfrompurchase_table
wherecustomerid=custid");
6.While(dbResult.rs.next())...{
7.Nodeitemnode=customerXML.createNode(dbResult.getString(1));
8.customerXML.appendNode(itemnode,"/Customer/Items",false);
}
9.customerXML.find("/Customer/Items/item[@price>15.0and@price<25.5]",true);
10.for(inti=0;i<customerXML.currentFind.getLength();i++)...{
11.System.out.println(customerXML.getValue("@description",i));
}
第一个查询(第 2 行)返回给定客户的 custXML 列中的 XML 数据。将这个 XML 字符串传递给 DOM 包装器的构造器(第 3 行),DOM 包装器进而使用 XML 解析器实例化一个代表 XML 数据的对象层次结构。
注意:因为客户 XML 中还没有任何 Items 元素(这符合我们在模型中定义的 XML 模式),所以我们创建一个新的 Items 元素(第 4 行),并把它作为子元素追加到 Customer 元素中。
第二个查询(第 5 行)从数据库中获取这位客户购买的商品的列表。将列表中的每个商品(第 7 行)追加到 DOM 对象层次结构中 Customer/items 路径的下面(第 8 行)。
最后,使用 XPath 在 DOM 对象层次结构中搜索给定价格范围内的所有商品(第 9 行),并输出搜索到的每个商品的说明(第 10 行)。
第二种情况 —— 所有数据在数据库中存储为关系形式
因为数据没有存储为 XML 格式,所以需要在查询中使用 SQL/XML 发布函数执行转换。
清单 7. 使用 SQL/XML 发布函数执行转换
1.Statementdbstmt=conn.createStatement();
2.ResultSetdbResult=dbstmt.executeQuery("selectxmlelement(name"Customer",
xmlattributes(customeridas"customerid"),
xmlattributes(fnameas"firstname"),
xmlattributes(lnameas"lastname")
)fromcustomer_tablewherecustomerid=custid");
3.XMLParsecustomerXML=newXMLParse(dbResult.getString(1));
5.dbResult=dbstmt.executeQuery("selectxmlelement(name"items",
xmlelement(name"item",
xmlattributes(itemidas"id"),
xmlattributes(descriptionas"description"),
xmlattributes(priceas"price"),
xmlattributes(dateas"purchaseDate")
)
)frompurchase_tablewherecustomerid=custid");
6.if(dbResult.rs.next())...{
7.Nodeitemsnode=customerXML.createNode(dbResult.getString(1));
8.customerXML.appendNode(itemsnode,"/Customer",false);
}
9.customerXML.find("/Customer/Items/item[@price>15.0and@price<25.5]",true);
10.for(inti=0;i<customerXML.currentFind.getLength();i++)...{
11.System.out.println(customerXML.getValue("@description",i));
}
所以,即使数据库中没有 XML,仍然可以用 SQL 创建关系数据的 XML 视图。另外,在查询中生成商品 XML 的同时,我们添加了外层的 Items 元素。现在,只需将商品 XML 添加到客户 XML 中。应用程序的其余部分是相同的。
与纯对象模型相比使用 XML 模型的好处
数据对象包装器在应用程序代码中占很大的比例,这会大大分散开发人员对管理数据对象的业务逻辑的注意力。另外,这些多余的代码会导致:
- 额外的成本
- 更多的 bug
- 更长的应用程序开发周期
- 难以移植的代码
- 当数据模式中发生任何修改时,需要修改或重新生成对象层次结构
- 代码更难维护
- 没有内置的数据检验功能
- 需要有更多的文档来解释包装器对象
- 对于对象层次结构中的高级搜索和导航等功能,需要相当复杂的逻辑实现
- 由每个业务对象处理数据序列化
- 如果使用工具进行映射,应用程序就被限制在这种工具上,难以更换工具
通过使用 XML 编程方法,就可以取消整个包装器对象层次结构,让开发人员将注意力集中在业务逻辑上,而不会为业务数据结构分心。XML 可以给应用程序开发带来以下好处:
- 减少代码,从而提高质量、降低成本并提高灵活性。
- 促进 RAD 开发。
- XPath 解析器已经内置了高级搜索和导航功能。
- XML 模型内置了约束检查和模式检验功能。
- 模型内置了持久化功能。任何时候都可以把 XML 数据层次结构存储到文件、字符串或流中。
- 不需要额外的工具。
- 这种方法向业务逻辑公开了关系和数据层次结构。在业务对象代码中,很难了解要操作的业务数据结构的格式(也就是,对业务代码隐藏了数据模型)。在关系环境中,这是必要的;但是在 XML 环境中,这可能是一个缺点。
- 业务逻辑代码容易理解,因为 XPath 描述了数据的性质以及数据与业务结构的关系。
采用 XML 模型时所涉及的问题和解决方案
如果关系数据没有存储为 XML 格式,就必须把它们映射到 XML。尽管大多数关系数据库厂商都提供了相关工具,但是映射过程非常繁琐。但是,由于 DB2 和 Microsoft® SQL Server 等数据库服务器引入了纯 XML 功能,将 XML 数据分解并映射到关系表不再是必需的。通过使用 XQuery 和 XML 索引,现在可以在应用程序中按原样搜索和获取存储的 XML 数据,采用的方式与从数据库获取大字符对象相同。
对于在数据库中存储为纯 XML 的数据,需要了解如何用 SQL/XML 函数和 XQuery 执行查询。应该先学习简单的 XPath 搜索,然后使用复杂的 XQuery,这样比较容易掌握 XML 查询。
了解并精通 DOM API 及其实现,以及掌握如何使用 XPath 导航和搜索 XML 层次结构,可能有点儿难度。可以使用 本文附带的 helper 类 减少对 DOM API 的直接调用。这个 helper 类封装了 DOM API 并公开更自然的 API,可以从应用程序代码调用这些 API。它提供了实例化和序列化 XML 模型以及在 XML 实例中搜索和修改数据或元数据所需的所有功能。包装器类还在必要时处理 XSL 转换、名称空间和模式检验。
在应用程序的业务逻辑中直接嵌入 DOM API 是一种低效率的做法,因为对 XML 模式的任何修改都要求对应用程序代码做大量修改。使用许多 API 调用在层次结构中导航;这会降低代码的可读性。导航或修改的数据对象不如使用用户定义的对象包装器时那么明显。包装器类避免了在业务逻辑中嵌入 DOM API 调用。因为这个包装器类使用 XPath 导航 DOM,所以如果对模式的任何修改影响到应用程序代码,那么只需修改应用程序中受影响的包装器 API 调用中的 XPath 字符串。另外,因为 XPath 指出了要操作的 XML 节点在层次结构中的位置,所以应用程序代码的可读性非常高。
结束语
业务应用程序主要关注创建、操作、存储和表示业务数据。为业务数据建立数据对象包装器是为了让业务逻辑更容易处理业务数据。但是,创建和维护这些数据对象包装器的成本很高,会使开发人员过分关注数据处理逻辑,而分散了对业务逻辑的注意力。
通过使用 XML 数据模型,就可以取消整个数据对象包装器层次结构,让开发人员将注意力集中在业务逻辑上,而不会为业务数据管理分心。通过使用 DOM 包装器类,应用程序代码可以与 DOM API 隔离开。使用 XPath 进行导航可以明确指出操作的业务数据中的关系,使应用程序代码更容易理解。
在理想情况下,数据应该在数据库中存储为纯 XML;但是即使数据存储在关系表中,仍然可以在应用程序中先将数据转换为 XML,然后再处理数据,这种做法在许多情况下是有意义的。
如果包装在对象层次结构中的数据结构可以用 XML 进行格式化,而且对象层次结构的主要用途是操作这些数据结构并向业务逻辑公开它们,那么可以考虑用 DOM 替代包装器对象层次结构。
在 本系列 的第 2 部分中,学习如何在自己的 DB2 应用程序中使用 XML 应用程序体系结构。
下载
描述
名字
大小
下载方法
用于 Java 的 DOM 和 XPath 包装器类
XMLParse.java |
30KB |
HTTP |
参考资料
学习
分享到:
相关推荐
DB2 pureXML 是 IBM 推出的一款数据库产品,专为处理 XML 数据设计。它提供了对 XML 数据的强大支持,包括高效存储、查询和索引功能。pureXML 支持原生 XML 数据类型,允许XML文档以结构化的形式存储在数据库中,...
- 数据模型:了解关系数据模型,实体关系图(ER图)及其在DB2中的应用。 2. **DB2安装与配置**: - 安装过程:在不同操作系统(如Windows、Linux、Unix)上的安装步骤和注意事项。 - 配置参数:理解并掌握DB2...
传统的数据库管理系统通常采用关系模型,这使得直接存储和查询 XML 数据变得复杂且效率低下。因此,开发出能够有效管理 XML 数据的技术变得至关重要。 - **需求**:随着企业数据量的增长以及数据结构的复杂化,传统...
- **支持面向对象编程**:能够实现复杂的数据模型。 - **支持多媒体应用程序**:适用于图像、视频等多媒体数据的处理。 - **增强的备份和恢复能力**:确保数据的安全性和完整性。 - **支持存储过程和触发器**:提高...
9. **XML支持**:DB2对XML数据的支持,包括XML数据类型、XML索引以及XML模式验证。 10. **Java和.NET集成**:DB2提供了与Java和.NET环境的紧密集成,包括JDBC和ODBC驱动,理解这些接口的使用是应用开发的关键。 ...
无论是使用Java、C#、Perl还是Python,开发人员都可以轻松地解析和生成XML文档,这极大地促进了不同编程环境之间的数据共享。 ### XML与ASP的关系 #### XML与ASP的联系 ASP(Active Server Pages)是一种服务器端...
在数据库设计部分,书中涵盖了关系数据库模型、ER图(实体关系图)的绘制,以及如何使用DB2的数据定义语言(DDL)创建数据库表。此外,还会介绍如何管理数据库对象,如索引、视图和存储过程。 关于数据操作,读者将...
#### 第一部分:Java应用程序开发 - **Java语言基础** - **Java应用程序运行原理**:理解Java程序如何在Java虚拟机(JVM)上执行,包括类加载机制、内存分配等。 - **Java的开发与运行环境安装配置**:熟悉Java开发...
1. **纯XML支持**:DB2 9引入了对XML数据的原生存储,允许直接在数据库中存储和查询XML文档,无需进行XML到关系数据的转换。 2. ** Federated Database**:联邦数据库功能允许DB2透明地访问和集成来自不同源的数据,...
XML的广泛支持催生了一系列相关技术,如DOM(文档对象模型)用于解析和操作XML文档,XSLT(可扩展样式表语言转换)用于转换XML数据,SVG(可缩放矢量图形)用于创建图形,VRML(虚拟现实建模语言)用于3D场景描述,...
这些知识点涵盖了DB2的基础概念、数据库设计、数据模型、数据库管理和开发等多个方面,是准备IBM DB2认证考试的重要学习材料。通过深入理解和实践,考生能够更好地掌握DB2的使用和管理,从而提升其在数据库领域的...
1. **数据库基本概念**:首先,了解数据库的基本概念至关重要,包括数据模型(如关系模型)、数据库管理系统(DBMS)、表、索引、视图等。DB2支持SQL标准,允许通过SQL语句进行数据查询、插入、更新和删除。 2. **...
- **结构化存储(Structured Storage)**:最灵活的方式,通过创建专门的数据模型来存储XML,同时保持XML的层次结构,并能利用关系型数据库的优势,如索引和查询优化,实现了XML和关系数据的融合。 在使用Delphi...
DB2支持XML数据类型和XQuery,允许对存储为XML的数据进行复杂的查询操作。这使得DB2特别适合需要处理XML数据的应用程序。 本教材还详细介绍了DB2不同的版本,每个版本适合市场不同部分的需求,强调了DB2在不同硬件...
这个"DB2课件"包含了IBM软件培训的DB2编程大师系列视觉教程,共有四卷,分别为Vol 1至Vol 4。这些PPT文件很可能详细介绍了DB2的各个方面,包括但不限于数据库基础、SQL语言、事务处理、存储过程、触发器、索引、安全...
1. 数据库类型:DB2支持多种数据库类型,如SQL、XML等,适用于不同场景的数据存储需求。 2. 安装与配置:DB2的安装过程通常涉及服务器选择、许可设置、实例创建等多个步骤。解压即用的特性简化了这一过程,用户只需...
- **定义**: DB2 pureXML是一种专为存储和管理XML数据设计的功能。 - **优势**: - 直接在数据库中存储和查询XML文档。 - 支持XQuery标准,提供强大的查询能力。 - 提升了XML数据的存储效率和查询性能。 ##### 10...
- **关系模型**:DB2基于标准的关系数据库模型,以表格形式存储数据,通过行和列表示数据实体及其关系。 - **SQL支持**:支持结构化查询语言(SQL),用于数据查询、插入、更新和删除操作。 - **事务处理**:提供...