XML - 管理数据交换/数据库和 XML
上一章 | 下一章 |
← XMLHTTP | SyncML → |
学习目标
|
术语原生 XML 数据库:在 1999 年后变得流行起来,当时软件 AG 公司发布了其原生 XML 服务器 Tamino 的第一个版本,其中包括一个原生 XML 数据库。原生数据库的定义是
"[d]efines a (logical) model for an XML document and stores and retrieves documents according to that model." (Bourret, 2002)"
为了对 XML 中的数据进行建模,使用两种主要方法:数据中心文档和文档中心文档。
- 数据中心文档(用于数据传输)具有相当规则的结构,顺序通常无关紧要,并且混合内容很少或没有。
- 文档中心文档(通常用于人类消费)具有不太规则或不规则的结构,元素的顺序非常重要,并且包含大量混合内容。
原生数据库的示例
产品 | 开发者 | 许可证 | 数据库类型 |
---|---|---|---|
Tamino | Software AG | 商业 | 专有。通过 ODBC 关系型。 |
XediX 多媒体解决方案 | XediX Tera 解决方案 | 商业 | 专有 |
eXist | Wolfgang Meier | 开源 | 关系型 |
dbXML | dbXML Group | 开源 | 专有 |
Xindice | Apache 软件基金会 | 开源 | 专有(基于模型) |
eXist 是一项开源努力,旨在开发一个原生 XML 数据库系统,与现有的 XML 开发工具(如 Apache 的 Cocoon)紧密集成。数据库易于部署,可以独立运行,在 servlet 引擎内部运行,或直接嵌入应用程序。
eXist 中提供的一些功能,以及大多数原生 XML 数据库中都可以找到的功能是
- 无模式存储 - 文档不必与模式或文档类型关联,这意味着它们只允许格式良好。
- 集合 - 集合在文件系统中扮演类似于目录的角色。提交查询时,用户可以选择集合层次结构的特定部分,甚至可以选择数据库中包含的所有文档。
- 查询语言 - 原生 XML 数据库支持的最流行的查询语言是 XPath(带有跨多个文档查询的扩展)和 XQuery。
IBM、Microsoft、Oracle 和 Sybase 等数据库供应商已经开发了工具来帮助将 XML 文档转换为关系型表。
让我们看看 IBM 和 Oracle
DB2 XML 扩展器通过用户定义函数和存储过程提供对 XML 数据的访问、存储和转换。它提供了 2 种关键存储模型:XML 列和XML 集合。
1. XML 列:将整个 XML 文档作为 DB2 列数据进行存储和检索。当 XML 文档已经存在或需要以其实体存储 XML 文档时,建议使用 XML 列。
2. XML 集合:从关系型表的集合中组合 XML 文档。
数据访问定义 (DAD) 文件用于 XML 列和 XML 集合方法,以定义数据库表和 XML 文档结构之间的“映射”。
<Xcollection> 指定 XML 数据要从 XML 文档分解到关系型表的集合,或者要从关系型表的集合组合到 XML 文档。
DAD 文件使用以下节点类型定义 XML 文档树结构
- root_node - 指定文档的根元素。
- element_node - 标识元素,可以是根元素或子元素。
- text_node - 表示元素的 CDATA 文本。
- attribute_node - 表示元素的属性。
<?xml version="1.0"?>
<!DOCTYPE DAD SYSTEM ""c:\dxx\samples\db2xml\dtd\dad.dtd">
<DAD>
...
<Xcollection>
<SQL_stmt>
...
</SQL_stmt>
<prolog>?xml version="1.0"?</prolog>
<doctype>!DOCTYPE Order SYSTEM
""c:\dxx\samples\db2xml\dtd\getstart.dtd""</doctype>
<root_node>
<element_node name="Order"> --> Identifies the element <Order>
<attribute_node name="key"> --> Identifies the attribute "key"
<column name="order_key"/> --> Defines the name of the column,
"order_key", to which the
element and attribute are
mapped
</attribute_node>
<element_node name="Customer"> --> Identifies a child element of
<Order> as <Customer>
<text_node> --> Specifies the CDATA text for
the element <Customer>
<column name="customer"> --> Defines the name of the column,
"customer", to which the child
element is mapped
</text_node>
</element_node>
...
</element_node>
...
</root_node>
</Xcollection>
</DAD>
Oracle 的XML SQL 实用程序 (XSU) 使用一个模式映射,该映射定义了如何将表和视图(包括对象关系功能)映射到 XML 文档。Oracle 将数据库中的对象引用链转换为 XML 元素的分层结构。
CREATE TABLE Customers
{
FIRSTNAME VARCHAR,
LASTNAME VARCHAR,
PHONENO INT,
ADDRESS AddressType, // object reference
}
CREATE TYPE AddressType as OBJECT
{
ZIP VARCHAR (100),
CITY VARCHAR (100),
STREET VARCHAR (100),
}
从给定的对象关系模型生成的相应 XML 文档如下所示
<?xml version="1.0"?>
<ROWSET>
<ROW num="1">
<FIRSTNAME>JOHN</FIRSTNAME>
<LASTNAME>SMITH</LASTNAME>
<PHONENO>7061234567</PHONENO>
<ADDRESS>
<ZIP>30601</ZIP>
<CITY>ATHENS</CITY>
<STREET>123 MAIN STREEET</STREET>
</ADDRESS>
</ROW>
<!-- additional rows ... -->
</ROWSET>
XSU 可用于在 Java 环境中执行查询并从数据库中检索 XML。
import oracle.jdbc.driver.*;
import oracle.xml.sql.query.OracleXMLQuery;
import java.lang.*;
import java.sql.*;
// class to test XML document generation as String
class testXMLSQL {
public static void main(String[] args)
{
try {
// Create the connection
Connection conn = getConnection("root","");
// Create the query class
OracleXMLQuery qry = new OracleXMLQuery(conn,
"SELECT * FROM Customers");
// Get the XML string
String str = qry.getXMLString();
// Print the XML output
System.out.println("The XML output is:\n"+str);
// Always close the query to get rid of any resources..
qry.close();
} catch(SQLException e) {
System.out.println(e.toString());
}
}
// Get the connection given the user name and password.!
private static Connection getConnection(String username,
String password)
throws SQLException
{
// register the JDBC driver..
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
// Create the connection using the OCI8 driver
Connection conn =
DriverManager.getConnection(
"jdbc:oracle:thin:@dlsun489:1521:ORCL",username,password);
return conn;
}
}
XPath 是一种用于寻址 XML 文档部分的语言,是 XSLT 和 XPointer 使用的通用定位器。XPath 表达式是一系列由“ / ”分隔的定位步骤。每一步都选择一组节点,这些节点成为下一步的当前节点。表达式选择的节点集是在按顺序处理每个步骤后剩余的节点。
XQuery 是一种由万维网联盟 (W3C) 开发的查询语言。这项雄心勃勃的任务是开发第一个用于查询 Web 文档的全球标准。XQuery 是一种通用的标记语言,能够标记各种数据源的信息内容,包括结构化和半结构化文档、关系型数据库和对象存储库。
MySQL 有一个命令行工具用于对 MySQL 数据库执行查询;它有一个选项可以使用 XML 作为它们的输出格式。MySQL 还允许转换为 XML;更多信息可以在 将 MySQL 转换为 XML 中找到。MySQL 允许用户执行任何 SQL 查询。mysqldump 允许用户指定要转储的表以及指定 where 子句来限制要转储的行。在其 MySQL 5.1 的 Beta 版本中,添加了一些功能,包括新的 **XML 函数**。
为了理解这些新功能,我们将使用以下表格
CREATE TABLE Customers (doc VARCHAR(150));
INSERT INTO Customers VALUES
('
<person id="1">
<firstname>John</firstname>
<lastname>Smith</lastname>
<phoneno>123-5678</phoneno>
</person>
');
INSERT INTO Customers VALUES
('
<person id="2">
<firstname>Aminata</firstname>
<lastname>Cisse</lastname>
<phoneno>123-5679</phoneno>
</person>
');
INSERT INTO Customers VALUES
('
<person id="3">
<firstname>Lamine</firstname>
<lastname>Smith</lastname>
<phoneno>123-5680</phoneno>
</person>
');
MySQL 5.1 版本具有用于搜索和更改 XML 文档的函数:**ExtractValue()** 和 **UpdateXML()**。
- EXTRACTVALUE (XML_document, XPath_string);
此函数采用 2 个字符串参数:第一个参数对应于 XML_document 字符串,第二个参数是 XPath_string(XPath 表达式/定位器)。这将导致返回包含文档中值的字符串。
mysql> SELECT EXTRACTVALUE(doc,'//firstname') FROM Customers; +------------------------------------------+ | EXTRACTVALUE(doc,'//firstname') | +------------------------------------------+ | John | | Aminata | | Lamine | +------------------------------------------+ 3 rows in set (0.01 sec)
mysql> SELECT ExtractValue(doc,'/person[@id="3"]/firstname') as fname FROM Customers; +---------+ | fname | +---------+ | | | | | Lamine | +---------+ 3 rows in set (0.02 sec)
- UPDATEXML (XML_document, XPath_string, new_value);
此函数采用 3 个字符串参数:前两个参数类似于与 extractValue() 一起使用的参数,XML_document 和 XPath_string。第三个参数是将替换找到的值的新值。然后此函数将返回已更改的 XML。
mysql> SELECT UpdateXML(doc,'/person[@id="3"]/phoneno', '<phoneno>111-2233<phoneno>') FROM Customers; +------------------------------------------------------------------------------- ----------------------------------------------------+ | UpdateXML(doc,'/person[@id="3"]/phoneno','<phoneno>111-2233<phoneno>') | +------------------------------------------------------------------------------- ----------------------------------------------------+ | <person id="1"> <firstname>John</firstname> <lastname>Smith</lastname> <phoneno>123-5678</phoneno> </person> | | <person id="2"> <firstname>Aminata</firstname> <lastname>Cisse</lastname> <phoneno>123-5679</phoneno> </person> | | <person id="3"> <firstname>Lamine</firstname> <lastname>Smith</lastname> <phoneno>111-2233<phoneno> </person> | +------------------------------------------------------------------------------- ----------------------------------------------------+ 3 rows in set (0.00 sec)
目前(04/05/06)MySQL 5.1 并没有随安装程序一起提供(Beta 版本)。
详细信息可以在在线手册中找到
- 以及更多内容,请参阅 手册。