級(jí)別: 中級(jí) |
高級(jí)JAVA工程師, NORDSAN信息科技開(kāi)發(fā)有限公司
2003 年 3 月
本文闡述了一個(gè)解決方法,將數(shù)據(jù)采集與數(shù)據(jù)轉(zhuǎn)換分成兩個(gè)互相獨(dú)立的模塊,充分利用XSLT這一新興技術(shù)給我們帶來(lái)的便捷,將數(shù)據(jù)轉(zhuǎn)換這一環(huán)節(jié)從JAVA代碼中分離,帶給開(kāi)發(fā)人員一個(gè)全新的開(kāi)發(fā)思路,最大限度的提升軟件產(chǎn)品或項(xiàng)目中關(guān)系型數(shù)據(jù)向XML型數(shù)據(jù)轉(zhuǎn)換這一核心流程的開(kāi)發(fā)效率。
前言
數(shù)據(jù)交換是一個(gè)傳統(tǒng)的課題,隨著近兩年XML標(biāo)準(zhǔn)的出現(xiàn)和日益成熟,并很快成為各種復(fù)雜的異構(gòu)數(shù)據(jù)的交換得以實(shí)現(xiàn)的核心技術(shù)。JAVA作為一門(mén)針對(duì)網(wǎng)絡(luò)的純面向?qū)ο蟮木幊陶Z(yǔ)言,與XML結(jié)合得天衣無(wú)縫。由于兩者都具有平臺(tái)無(wú)關(guān)性,是數(shù)據(jù)交換領(lǐng)域里服務(wù)器端實(shí)現(xiàn)技術(shù)的首選。在java中對(duì)xml數(shù)據(jù)進(jìn)行硬編碼操作是目前開(kāi)發(fā)人員普遍采用的方式,但代碼的復(fù)用性和維護(hù)性很差,在數(shù)據(jù)交換格式的設(shè)計(jì)變更后,代碼將有翻天覆地的變更,造成了整個(gè)軟件產(chǎn)品的內(nèi)在不穩(wěn)定性,及開(kāi)發(fā)進(jìn)度的停滯甚至倒退。由于xml是一新興技術(shù),全球各個(gè)企業(yè)中也剛剛開(kāi)始建立起數(shù)據(jù)交換的概念,數(shù)據(jù)交換格式各有各的標(biāo)準(zhǔn),跨行業(yè),跨企業(yè)的數(shù)據(jù)交換由于數(shù)據(jù)格式的互不兼容的原因,是一個(gè)十分棘手的問(wèn)題。開(kāi)發(fā)人員往往在將xml數(shù)據(jù)格式化成企業(yè)自有系統(tǒng)所能識(shí)別的xml格式這個(gè)問(wèn)題上頻繁更改以前代碼或衍生出各種版本,陷入數(shù)據(jù)格式的泥沼之中。下面將要介紹的技術(shù)將解決這一問(wèn)題,將數(shù)據(jù)采集與數(shù)據(jù)轉(zhuǎn)換分成兩個(gè)互相獨(dú)立的模塊,充分利用XSLT這一新興技術(shù)給我們帶來(lái)的便捷,將數(shù)據(jù)轉(zhuǎn)換這一環(huán)節(jié)從JAVA代碼中分離,帶給開(kāi)發(fā)人員一個(gè)全新的開(kāi)發(fā)思路,最大限度的提升軟件產(chǎn)品或項(xiàng)目中關(guān)系型數(shù)據(jù)向XML型數(shù)據(jù)轉(zhuǎn)換這一核心流程的開(kāi)發(fā)效率。
傳統(tǒng)的DB-XML數(shù)據(jù)交換方式
關(guān)于XSLT
XSLT用于將一個(gè)XML文檔轉(zhuǎn)換成另一個(gè)XML文檔或另一種類(lèi)型的文檔,也就是將一個(gè)XML文檔轉(zhuǎn)換成瀏覽器所能識(shí)別的一種格式。這其中之一就是HTML。通常,XSLT將每個(gè)XML元素都轉(zhuǎn)換成一個(gè)HTML元素。 XSLT還可以向輸出文件中增加全新的元素,或去掉一些元素。它可以重新安排這些元素并對(duì)元素進(jìn)行分類(lèi),測(cè)試并確定顯示哪些元素等等。 描述這種轉(zhuǎn)換過(guò)程的一個(gè)常用說(shuō)法是:XSL用XSLT將一個(gè)XML來(lái)源樹(shù)轉(zhuǎn)換成另一個(gè)XML結(jié)果樹(shù)(或?qū)⒁粋€(gè)XML源文檔轉(zhuǎn)換成另一個(gè)XML結(jié)果文檔)。
鮮為人知的秘籍-xalan便捷的數(shù)據(jù)庫(kù)查詢功能
xalan-java是一套xslt處理器,用來(lái)將XML文件轉(zhuǎn)換為HTML,TEXT和XML等其他類(lèi)型文件格式。支持XSLT1.0和XPATH 1.0版。開(kāi)發(fā)人員可以通過(guò)命令行方式或在JAVA APPLET和SERVLET中使用,并可以作為自己開(kāi)發(fā)的應(yīng)用程序的類(lèi)庫(kù)使用。xalan-java實(shí)現(xiàn)的是transformation API for XML(TRaX)接口,此接口為jaxp1.2標(biāo)準(zhǔn)中的一部分。TraX提供一個(gè)模塊化的架構(gòu)和標(biāo)準(zhǔn)的api以執(zhí)行xml的轉(zhuǎn)換,并且會(huì)根據(jù)配置設(shè)定決定使用哪一個(gè)轉(zhuǎn)換器和xml語(yǔ)法分析器。
Xalan-java制訂的關(guān)于SQL的XSLT擴(kuò)展庫(kù)詳解
XSLT擴(kuò)展庫(kù)的概念
當(dāng)最基本的XSLT語(yǔ)法不能滿足的開(kāi)發(fā)工作時(shí),你一定設(shè)想開(kāi)發(fā)一套自己的XSLT擴(kuò)展語(yǔ)法,幸運(yùn)的是Xalan-Java讓你的這種想法變成現(xiàn)實(shí)。XSLT的擴(kuò)展元素和函數(shù)為像xalan這樣的XSLT處理器提供了強(qiáng)大的擴(kuò)展功能。Apache組織也提供一些擴(kuò)展庫(kù)支持,在JAVA開(kāi)源愛(ài)好者共同努力下,我們將獲得更多的可以工作在xalan/java上的擴(kuò)展,簡(jiǎn)化我們的開(kāi)發(fā)工作。這里我們主要介紹的是xalan-java自帶的SQL擴(kuò)展庫(kù)。
SQL擴(kuò)展庫(kù)
SQL擴(kuò)展的xml命名空間是http://xml.apache.org/xalan/sql, 它能實(shí)現(xiàn)的功能有通過(guò)JDBC驅(qū)動(dòng)建立數(shù)據(jù)庫(kù)連接,執(zhí)行一個(gè)SQL查詢并取得結(jié)果集。用于數(shù)據(jù)庫(kù)查詢的SQL語(yǔ)句可以在xsl文件中直接給出或者通過(guò)java程序傳入xsl文件。本文中的實(shí)例采用后一種方式,此方式更具有實(shí)用性。SQL擴(kuò)展庫(kù)中也有類(lèi)似于JDBC的結(jié)果集的概念。"流化"(streamable)的結(jié)果集是此擴(kuò)展庫(kù)取得結(jié)果集的默認(rèn)方式。如果你采用此模式,你一次只能從結(jié)果集中取出一條記錄,特別注意的是,在你的樣式表單中對(duì)結(jié)果集document使用XPATH表達(dá)式將可能導(dǎo)致不可預(yù)期的結(jié)果。XALAN庫(kù)中關(guān)于SQL的擴(kuò)展的核心java類(lèi)是org.apache.xalan.lib.sql.Xconnection,它提供了SQL擴(kuò)展的所有功能。Java的函數(shù)的名稱(chēng)就是xsl文件中sql擴(kuò)展功能函數(shù)的名稱(chēng)。下面介紹這個(gè)類(lèi)的幾個(gè)主要方法:
query()函數(shù)返回一個(gè)document,包含了jdbc中ResultSetMetaData中對(duì)結(jié)果集的描述信息和當(dāng)前記錄中各個(gè)字段的值。
上面是從java實(shí)現(xiàn)的層面簡(jiǎn)單介紹了一下xalan的sql擴(kuò)展庫(kù)的功能,下面就其在XLST中的具體使用方法,進(jìn)行詳細(xì)的講解。
通過(guò)JAVA程序創(chuàng)建數(shù)據(jù)庫(kù)連接池:
下面代碼將演示通過(guò)java程序建立一個(gè)SQL擴(kuò)展庫(kù)的連接池:
|
在XSLT中使用連接池建立數(shù)據(jù)庫(kù)連接
|
我們用db這個(gè)變量存儲(chǔ)一個(gè)數(shù)據(jù)庫(kù)連接,sql:new()聲明此變量是個(gè)數(shù)據(jù)庫(kù)連接;sql:connect($db, ‘sppixpool‘)是從名稱(chēng)為sppixpool的數(shù)據(jù)庫(kù)連接池中創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)連接,這個(gè)連接池由上一步的java程序片斷實(shí)現(xiàn); sql:getError($db)/ext-error用來(lái)打印連接數(shù)據(jù)庫(kù)的錯(cuò)誤信息,錯(cuò)誤信息的內(nèi)容對(duì)應(yīng)于java.sql.SQLException中的內(nèi)容; sql:disableStreamingMode($db)用來(lái)設(shè)置此連接為非流模式,以便返回結(jié)果集中的全部記錄,否則只能返回一條數(shù)據(jù)記錄。
在XSLT中進(jìn)行數(shù)據(jù)庫(kù)查詢
|
第一條語(yǔ)句聲明一個(gè)變量名稱(chēng)為query,這個(gè)變量的值是一條SQL語(yǔ)句"select * from cat",第二條語(yǔ)句執(zhí)行查詢并將查詢的結(jié)果賦給變量table。
Table是一個(gè)結(jié)果集變量,對(duì)應(yīng)xalan擴(kuò)展庫(kù)中的org.apache.xalan.lib.sql.SQLDocument,在xslt中,可以通過(guò) xpath的描述方式取出其內(nèi)部的各級(jí)對(duì)象。那所謂各級(jí)對(duì)象,具體包含哪些對(duì)象呢?xalan的文檔中并沒(méi)有明確的文字進(jìn)行說(shuō)明,但有下面幾個(gè)是常用的。Sql是根結(jié)點(diǎn)元素,下面的二級(jí)節(jié)點(diǎn)元素是row-set,這個(gè)節(jié)點(diǎn)類(lèi)似于JDBC中的ResultSet這個(gè)對(duì)象;自然row-set這個(gè)節(jié)點(diǎn)元素的下一級(jí)是row這個(gè)節(jié)點(diǎn)元素,它對(duì)應(yīng)于一條數(shù)據(jù)庫(kù)記錄。你可以通過(guò)xpath的方式訪問(wèn)到這條記錄,語(yǔ)法是
|
(注:其中的$table這個(gè)變量在上一節(jié)中曾經(jīng)定義過(guò),對(duì)應(yīng)數(shù)據(jù)庫(kù)中的表)
row下面是col,對(duì)應(yīng)每個(gè)數(shù)據(jù)庫(kù)表中的一條記錄的一個(gè)字段。另外col有一個(gè)方法text(),就是取出col中的值的文本表示形式。column-label是col的一個(gè)屬性,記錄了字段的名稱(chēng)??梢酝ㄟ^(guò)xpath中@column-label的語(yǔ)法將其取出。
在XSLT中斷開(kāi)數(shù)據(jù)庫(kù)連接
|
其中的$db是上面曾定義過(guò)的數(shù)據(jù)庫(kù)連接,這行語(yǔ)句的功能就是在數(shù)據(jù)庫(kù)連接使用完后,斷開(kāi)數(shù)據(jù)庫(kù)的連接。
駕馭xalan,輕松實(shí)現(xiàn)關(guān)系型數(shù)據(jù)庫(kù)到XML的數(shù)據(jù)交換
前面詳細(xì)介紹了xalan從關(guān)系型數(shù)據(jù)庫(kù)獲取數(shù)據(jù)的方法,下面將給出一個(gè)完整且有應(yīng)用價(jià)值的例子,通過(guò)它,你將真正掌握這種簡(jiǎn)單快捷的數(shù)據(jù)交換方式。
這個(gè)例子要做的事情很簡(jiǎn)單,就是從一個(gè)名稱(chēng)為sppix的關(guān)系型數(shù)據(jù)庫(kù)中的名稱(chēng)為cat的表中,根據(jù)條件查詢出一組數(shù)據(jù),并按照特定的xml格式輸出到文件中(當(dāng)然在真正應(yīng)用中,這個(gè)xml數(shù)據(jù)只是個(gè)中間體,有了它,你可以隨心所欲的進(jìn)行任何xml操作)。為了讀者便于調(diào)試,本例中的關(guān)系型數(shù)據(jù)庫(kù)采用流行且免費(fèi)的mysql數(shù)據(jù)庫(kù),jdk的版本是1.3.1,java程序要用到的全部類(lèi)庫(kù)在本文最后的“有用的資源和參考資料”中給出。整個(gè)過(guò)程由一個(gè)java程序調(diào)用xsl模版文件完成,java程序的流程是讀入xsl文件,將標(biāo)準(zhǔn)sql格式的查詢語(yǔ)句倒入到內(nèi)存的xsl對(duì)象中,通過(guò)xalan輸出到xml文件。Java程序負(fù)責(zé)數(shù)據(jù)采集,xsl模版文件負(fù)責(zé)數(shù)據(jù)的轉(zhuǎn)換和呈現(xiàn)。這個(gè)實(shí)例代碼的一個(gè)特別之處就在于xsl文件只需撰寫(xiě)一次,無(wú)需更改,便適應(yīng)任何的查詢要求,生成統(tǒng)一的xml格式,因?yàn)閷?duì)數(shù)據(jù)的采集都已經(jīng)隱藏在java文件中了;另一方面,在工程項(xiàng)目中,程序無(wú)需關(guān)心生成的xml格式,在用戶或合作開(kāi)發(fā)者要求改變xml的交換格式時(shí),無(wú)需更改java代碼,只需簡(jiǎn)單的更改一下xsl文件,便可以滿足要求,極大的提高的java代碼的可復(fù)用型,這在實(shí)際的工作中將提高整個(gè)開(kāi)發(fā)組的工作效率。Java的強(qiáng)大加上x(chóng)alan的簡(jiǎn)捷清晰,給數(shù)據(jù)交換方式注入了新的生命力。
在閱讀如下章節(jié)之前,你應(yīng)該具有java通過(guò)jdbc訪問(wèn)mysql數(shù)據(jù)庫(kù)的基本技能,并掌握xml的概念及如何通過(guò)java操縱xml,并掌握xpath的概念和知識(shí)。另外至少應(yīng)該知道xalan是做什么用的,如果對(duì)xalan還感到陌生建議先閱讀有關(guān)xalan的入門(mén)資料。在此并不會(huì)對(duì)以上技術(shù)的基本入門(mén)知識(shí)進(jìn)行介紹。
搭建數(shù)據(jù)庫(kù)環(huán)境
本例中在MYSQL數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)名稱(chēng)為sppix的數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)中建立表并插入樣例數(shù)據(jù)的sql語(yǔ)句如下:
|
這個(gè)表記錄了貓咪的基本信息,每個(gè)字段的含義依次是貓咪的編號(hào),愛(ài)稱(chēng),性別(F代表雌性,M代表雄性)及體重。
撰寫(xiě)xsl文件
xsl文件的文件名為sample1.xsl
|
java代碼的設(shè)計(jì)思想
一個(gè)簡(jiǎn)單而完整的java實(shí)現(xiàn)代碼:
|
運(yùn)行結(jié)果
生成一個(gè)名稱(chēng)為result.xml的文件:
|
后記
讀過(guò)此文,你一定會(huì)對(duì)XSLT和xalan有一個(gè)新的認(rèn)識(shí),一定會(huì)說(shuō)“啊,xalan居然還可以這樣用”。是的,如果僅僅將xslt當(dāng)作一種html時(shí)代css樣式表的替代品,控制一下網(wǎng)頁(yè)的輸出或作為一種數(shù)據(jù)呈現(xiàn)的終端工具,這種想法就過(guò)于狹隘了。我們應(yīng)該站在更高一些的角度,俯視一門(mén)新興技術(shù)真正能給我們的開(kāi)發(fā)方式和開(kāi)發(fā)思想帶來(lái)怎樣的革命。在以后的文章中我將對(duì)xalan的其他高端技術(shù)進(jìn)行一一介紹,技術(shù)永無(wú)止境!
聯(lián)系客服