Oracle发明了XML SQL(XSU)Java API来将XML转换成SQL,或者反过来映射。在你可以执行这种映射之前,你必须先创建你将要映射XML文档到的表。XSU映射XML元素到指定的数据库表中的列。你应该清楚使用XSU来将XML文档映射到数据库表的时候将不会保存这个XML文档的属性,但是你可以在保存文档之前先对该文档进行XSLT转换,将你需要的属性存储XML属性,这样你可以映射到数据库表中的列。XSU还让你从数据库中检索数据,并且将数据转换成XML文档。同样,使用XSU产生的XML文档不会包含属性,然而,你可以在XSU之后通过对XSU所产生的文档执行XSLT转换来重新创建属性。
在这篇文章中,你将了解将带有元素和属性的XML文档转换到Oracle 10g数据库中的表的必要步骤,并且通过将数据库列映射到XML文档来检索带有属性的XML文档的步骤。需要注意的是使用XSU来存储XML文档的功能并不仅仅限于Oracle,你可以在如MySQL等其他的关系数据库中方便的使用。
前期准备
为了使用Oracle数据库,你需要安装Oracle 10g数据库,包括样本数据库模式。你还需要XSU Java API classes。首先,下载并安装XDK 10g。将下面的三个文件加入到你的CLASSPATH变量中,其中 代表你的安装路径:
/lib/xsu12.jar
/lib/xmlparserv2.jar
/lib/xdb.jar
创建一个数据库实例;在这篇文章中我将使用叫做OracleDB的数据库实例。为了和数据库建立JDBC连接,你需要合适的JDBC驱动;对于Oracle 10g,将下面的三个文件加入到你的CLASSPATH变量中,其中 是你安装Oracle 10g的目录:
/jdbc/lib/ojdbc14.jar
/LIB/servlet.jar
/jdbc/lib/classes12dms.jar
在这篇文章中我将使用catalog.xml的XML文档作为例子,如Listing 1所示。
你需要创建一个数据库表,该表的每一列将对应示例XML文档中每个元素标签和属性。你可以使用下面的SQL脚本来创建一个包含合适列的、名为JOURNAL的数据库表:
CREATE TABLE OE.JOURNAL ( JOURNAL_TITLE VARCHAR(255), PUBLISHER VARCHAR(255), EDITION VARCHAR(255), ARTICLE_SECTION VARCHAR(255), TITLE VARCHAR(255), AUTHOR VARCHAR(255) ); |
如果你使用XSU直接来存储Listing 1的XML文档,只有XML文档中的元素标签会被存储。但是你可以保存XML文档中的属性,首先将这些属性转换成元素,然后保存经过转换的XML文档、而不是原始的文档。通过对原始的文档应用XSLT stylesheet,你可以将这些属性转换成元素。
你可以使用OracleXMLSave类将XML文档保存在数据库中。下面是具体的步骤。首先,导入OracleXMLSave类:
import oracle.xml.sql.dml.OracleXMLSave; |
接着,创建数据库连接:
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@ : : ," " ,"" "); |
前面的代码中有几个占位符,用尖括号隔开,你必须使用你自己的具体信息来替换它们:
是数据库主机名.
是数据库的端口.
是数据库的SID.
是用于登录数据库的用户名.
是登录数据库的密码.
你可以从你的 /NETWORK/ADMIN/tnsnames.ora文件中获得 、 和 字段的值。
新建OracleXMLSave类的一个实例:
OracleXMLSave oracleXMLSave = new OracleXMLSave(conn, "JOURNAL"); |
在前面的一行中,“JOURNAL”是你在前期准备中所新建的数据库表的名字。
你需要通过对示例的XML文档应用XSLT来将这个文档中的属性转换成元素标签。首先,将一个XSLT stylesheet分配给那个OracleXMLSave对象。这个步骤将引发在XML文档保存之前先转换输入的XML文档。
Reader xsltReader=new FileReader( new File("c:/catalog/input.xslt")); oracleXMLSave.setXSLT(xsltReader, null); |
这个用于将示例XML文档中的属性装换成元素的XSLT会在Listing 2列出。
应用这个stylesheet将示例XML文档修改成如下所示。注意原始catalog.xml文档中的属性已经被转换成元素:
Oracle Magazine Oracle Publishing Sept-Oct 2003 XML Julie Basu Oracle Magazine Oracle Publishing Nov-Dec 2003 SQL Cameron ORourke |
接下来为将放入数据库行中的元素设置标签。设置行标签为‘null’将使得最顶层的标签对应到数据库的行。在本例中,设置行标签为journal,这样示例XML文档中每个journal标签将对应到数据库中的一行:
oracleXMLSave.setRowTag("journal"); |
最终,使用下面的代码,将示例XML文档转成一个数据库表:
oracleXMLSave.insertXML(oracleXMLSave.getURL( file://c:/catalog/catalog.xml)); |
在这个例子中,XSLT文件input.xslt被应用到示例XML文档,然后这个文档被保存到数据库中。
SQL数据库到XML文档的映射
为了将数据进行反向的映射——从数据库表到XML——你使用OracleXMLQuery类。
XSU会为数据库表的每个列创建一个对应的XML元素,但是不会创建元素的属性。同样,为了创建元素的属性,你对从数据库表中创建的XML文档应用XSLT。
下面是具体的步骤。首先,导入OracleXMLQuery类:
import oracle.xml.sql.query.OracleXMLQuery; |
OracleXMLQuery query = new OracleXMLQuery( conn, "SELECT JOURNAL_TITLE, PUBLISHER, EDITION, " + "ARTICLE_SECTION, TITLE, AUTHOR FROM JOURNAL"); |
在前面的代码中,conn是用于查询数据库的JDBC连接。
设置你想要OracleXMLQuery对象用来产生最终包含元素属性的XML文档的XSLT stylesheet:
Reader xsltReader=new FileReader( new File("c:/catalog/output.xslt")); query.setXSLT(xsltReader, null); |
你可以在Listing 3中看到这个output.xslt的XSLT。
接下来,设置行标签为被产生的XML文档中将对应到数据库表行的元素标签。
query.setRowTag("journal"); |
最终,从JOURNAL数据库表中产生XML文档:
String xmlString=query.getXMLString(); |
在前面的例子中,OracleXMLQuery实例对XSU产生的XML文档应用设好的output.xslt的stylesheet,将产生(重建)在Listing 1中列出的XML文档。带有属性的XML文档也可以通过修改SQL SELECT语句来产生,而不是应用XSLT,但是这样产生的XML文档中root元素是ROWSET,而不是catalog,并且行元素是ROW,而不是journal。下面给出能够为JOURNAL._TITLE、PUBLISHER、EDITION和ARTICLE_SECTION列创建属性的SQL语句:
SELECT JOURNAL_TITLE "@title", PUBLISHER "@publisher", EDITION "@edition", ARTICLE_SECTION "@section", TITLE, AUTHOR FROM JOURNAL |
换句话说,你看到的两个方法将XML文档存储在数据库中,然后检索出原始文档的一份拷贝。在这个项目的可下载代码中,你会找到XMLToDatabase.java程序,以及样本XML文件。
所以,你已经了解了一种使用XSLT stylesheet来存储和检索XML元素属性的变通方法。虽然这篇文章仅仅是专注于XSU原生的从单个数据库表存储和检索文件的能力,假如你想要多做一些额外的工作,你可以将整个XML分解成具有单个表关系的小块,然后插入到表中。你还可以使用可更新视图。