久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用Digester簡化XML文檔處理...

 dwedit2000 2006-07-17
用Digester簡化XML文檔處理 (2)
作者:仙人掌工作室 來源:賽迪網(wǎng) 發(fā)布時間:2002.11.25
【Java專區(qū)】  【網(wǎng)絡(luò)安全】  【網(wǎng)管專區(qū)】  【linux專區(qū)】  【進入論壇】  【IT博客】 

指定模式和規(guī)則

Digester框架以模式(Pattern)和規(guī)則(Rule)為基礎(chǔ)處理輸入的XML,。模式必須與XML元素匹配,,包括其名字和在文檔樹內(nèi)的位置。描述匹配模式的語法類似于XPath匹配模式,,例如:catalog模式匹配頂層的<catalog>元素,,catalog/book模式匹配直接嵌套在<catalog>元素內(nèi)的<book>元素(但不匹配文檔內(nèi)其他位置的<book>元素)

所有的模式都必須指定其完整名稱——從根元素開始的完整路徑,。唯一的例外是包含通配符(“*”)的模式,,例如*/name模式匹配XML文檔內(nèi)任何位置的<name>元素。但是根元素不必特別指出,因為所有的路徑都是從根元素開始的絕對路徑,。

當(dāng)Digester發(fā)現(xiàn)一個指定的模式,,它就執(zhí)行關(guān)聯(lián)的任務(wù)。由此可見,,Digester框架顯然與SAX解析器有著密切的關(guān)系(實際上,,Digester類實現(xiàn)了org.xml.sax.ContentHandler,并維護著解析棧),。所有在Digester中使用的規(guī)則必須擴展org.apache.commons.digester.Rule,,后者本身提供了一些類似于SAX的ContentHandler回調(diào)函數(shù)的方法。例如,,當(dāng)遇到匹配元素的開始標(biāo)記和結(jié)束標(biāo)記時,,begin()方法和end()方法將分別被調(diào)用。

一旦遇到匹配元素的內(nèi)容,,body()方法被調(diào)用,;最后被調(diào)用的方法是finish(),這個方法在匹配元素的結(jié)束標(biāo)記處理完畢之后被調(diào)用,,用來執(zhí)行可能需要的事后清理任務(wù),。然而,大多數(shù)時候我們不必關(guān)注這些方法,,因為框架提供的標(biāo)準(zhǔn)規(guī)則很可能已經(jīng)提供了所有必需的功能,。

要反配制一個文檔,首先創(chuàng)建一個org.apache.commons.digester.Digester類的實例,,如果必要的話,,進行一些配置操作,指定必需的模式和規(guī)則,,最后向parse()方法傳遞一個XML文件的引用。下面的DigesterDriver示范了這一處理過程(必須在命令行上指定輸入XML文檔的名稱),。

import org.apache.commons.digester.*;
                        import java.io.*;
                        import java.util.*;
                        public class DigesterDriver {
                        public static void main( String[] args ) {
                        try {
                        Digester digester = new Digester();
                        digester.setValidating( false );
                        digester.addObjectCreate( "catalog", Catalog.class );
                        digester.addObjectCreate( "catalog/book", Book.class );
                        digester.addBeanPropertySetter( "catalog/book/author", "author" );
                        digester.addBeanPropertySetter( "catalog/book/title", "title" );
                        digester.addSetNext( "catalog/book", "addBook" );
                        digester.addObjectCreate( "catalog/magazine", Magazine.class );
                        digester.addBeanPropertySetter( "catalog/magazine/name", "name" );
                        digester.addObjectCreate( "catalog/magazine/article", Article.class );
                        digester.addSetProperties( "catalog/magazine/article", "page", "page" );
                        digester.addBeanPropertySetter( "catalog/magazine/article/headline" );
                        digester.addSetNext( "catalog/magazine/article", "addArticle" );
                        digester.addSetNext( "catalog/magazine", "addMagazine" );
                        File input = new File( args[0] );
                        Catalog c = (Catalog)digester.parse( input );
                        System.out.println( c.toString() );
                        } catch( Exception exc ) {
                        exc.printStackTrace();
                        }
                        }
                        }

在上面的代碼中,,我們首先創(chuàng)建了Digester類的一個實例digester,然后指定它不要用DTD驗證XML文檔的合法性——這是因為我們沒有為XML文檔定義DTD,。接下來,,我們指定了模式和關(guān)聯(lián)的規(guī)則:ObjectCreateRule創(chuàng)建指定類的一個實例,并將它壓入解析棧,。SetPropertiesRule把Bean屬性設(shè)置成當(dāng)前XML元素的屬性值——規(guī)則的第一個參數(shù)是XML屬性的名稱,,第二個參數(shù)是Bean屬性的名稱。

SetPropertiesRule獲取的是XML屬性的值,,而BeanPropertySetterRule獲取的是位于當(dāng)前元素內(nèi)的原始字符數(shù)據(jù)值,。使用BeanPropertySetterRule時不必指定要設(shè)置的Bean屬性名字,默認是當(dāng)前XML元素的名稱。在上面的例子中,,在匹配catalog/magazine/article/headline模式的規(guī)則定義中使用的就是默認值,。最后,SetNextRule彈出解析棧頂部的對象,,并把該對象傳遞給它下面對象的指定名稱的方法——通常用來把一個配置完畢的Bean插入父對象,。

注意,我們可以為同一個模式注冊多個規(guī)則,。如果注冊了多個規(guī)則,,則這些規(guī)則按照它們被加入到Digester的次序執(zhí)行,例如,,如果要處理catalog/magazine/article的

元素,,我們首先創(chuàng)建合適的article Bean,然后設(shè)置page屬性,,最后彈出完成后的article Bean,,并把它插入magazine。

調(diào)用任意方法

我們不僅可以設(shè)置Bean的屬性,,而且還可以調(diào)用堆棧內(nèi)對象的任意方法,。這通過CallMethodRule完成,我們只需指定方法名字,,如有必要,,再說明調(diào)用的參數(shù)類型和數(shù)量。CallParamRule用來定義傳遞給被調(diào)用函數(shù)的參數(shù)值,,參數(shù)值可以從當(dāng)前XML元素的命名的屬性獲取,,也可以從當(dāng)前元素包含的原始字符數(shù)據(jù)獲取。例如,,在前面實現(xiàn)DigesterDriver的例子中,,我們可以不用BeanPropertySetterRule,而是通過顯式調(diào)用屬性的set方法達到同樣的目的:

digester.addCallMethod( "catalog/book/author", "setAuthor", 1 );
                        digester.addCallParam( "catalog/book/author", 0 );

上面的第一行代碼給出了要調(diào)用的方法(即setAuthor()),,以及該調(diào)用需要的參數(shù)數(shù)量(即1),。第二行代碼的意思是從元素包含的字符數(shù)據(jù)獲取函數(shù)參數(shù)的值,把它作為參數(shù)數(shù)組的第一個傳入(即索引是0的數(shù)組元素),。如果我們指定了XML元素屬性的名稱(例如digester.addCallParam( "catalog/book/author", 0, "author" );),,則參數(shù)值將從當(dāng)前元素的相應(yīng)屬性值獲取。

這里必須注意的是,,“digester.addCallMethod( "pattern", "methodName", 0 );”這個語句不是指定了一個不帶參數(shù)的方法調(diào)用,,而是指定了帶有一個參數(shù)的方法調(diào)用,它的值就是當(dāng)前XML元素的字符數(shù)據(jù),!這樣,,我們又有了另一種替代BeanPropertySetterRule的辦法:

digester.addCallMethod( "catalog/book/author", "setAuthor", 0 );

如果要調(diào)用一個確實沒有參數(shù)的方法,,必須采用如下形式:digester.addCallMethod( "pattern", "methodName" );。

標(biāo)準(zhǔn)規(guī)則概要

下面簡要說明所有標(biāo)準(zhǔn)規(guī)則,。

創(chuàng)建

ObjectCreateRule:利用指定類的默認構(gòu)造函數(shù),,創(chuàng)建該類的一個對象,并把對象壓入棧,。當(dāng)元素處理結(jié)束時,,對象被彈出。被實例化的類可通過class對象或類的全稱給出,。

FactoryCreateRule:利用指定的工廠類創(chuàng)建一個對象,,把對象壓入棧。對于沒有提供默認構(gòu)造函數(shù)的類,,這一規(guī)則很有用,。用于該規(guī)則的工廠類必須實現(xiàn)org.apache.commons.digester.ObjectCreationFactory接口。

設(shè)置屬性

SetPropertiesRule:利用指定名稱的XML元素屬性值,,設(shè)置頂層Bean的一個或者多個指定名稱的屬性,。XML元素的屬性名稱和Bean的屬性名稱以String[]數(shù)組形式傳入該規(guī)則(通常用來處理

之類的結(jié)構(gòu))。

BeanPropertySetterRule:把頂層Bean的指定名稱的屬性設(shè)置成當(dāng)前XML元素包含的字符數(shù)據(jù),。(通常用來處理<page>10</page>之類的結(jié)構(gòu)),。

SetPropertyRule:設(shè)置頂層Bean的一個屬性。無論是Bean屬性的名稱,,還是賦予該屬性的值,,都在當(dāng)前XML元素中以屬性的形式指定,例如:<article key="page" value="10" />,。

管理父/子關(guān)系

SetNextRule:彈出棧頂?shù)膶ο?,把它傳遞給緊接其下的另一個對象的指定名稱的方法。通常用來把一個已經(jīng)初始化的Bean插入到父對象,。

SetTopRule:把棧里面上數(shù)第二的對象傳遞給頂層的對象,。當(dāng)子對象提供了一個setParenet方法時,這一規(guī)則很有用,。

SetRootRule:調(diào)用棧底對象的一個方法,,并把棧頂?shù)膶ο笞鳛閰?shù)傳入。

調(diào)用任意方法

CallMethodRule:調(diào)用頂層Bean的指定名稱的方法,。被調(diào)用的方法可以有任意多個參數(shù),,參數(shù)的值通過后繼的CallParamRule給出,。

CallParamRule:表示方法調(diào)用的參數(shù),。參數(shù)的值或者取自指定名稱的XML元素的屬性,或者是當(dāng)前元素包含的原始字符數(shù)據(jù),。這個規(guī)則要求用一個整數(shù)指定它在參數(shù)列表中的位置,。

通過XML指定規(guī)則

在前面的內(nèi)容中,我們用程序代碼的方式指定模式和規(guī)則,這些模式和規(guī)則都是在編譯的時候就已經(jīng)確定,,雖然從概念上來講比較簡單,,但卻不能說盡善盡美:Digester框架的總體目標(biāo)是在運行時識別和處理各種數(shù)據(jù)結(jié)構(gòu),但如果我們用編程的方法指定模式和規(guī)則,,則所有行為在編譯時已經(jīng)固定,!如果Java源程序中包含了大量固定的字符串,通常意味著程序在執(zhí)行某些配置操作,,這部分操作可以被(或許是應(yīng)該被)延遲到運行時進行,。

org.apache.commons.digester.xmlrules包解決了這個問題。這個包提供了一個DigesterLoader類,,它能夠從XML文檔讀取模式/規(guī)則對,,返回配置好的Digester對象。用來配置Digester對象的XML文檔必須遵從digester-rules.dtd,,這個DTD是xmlrules包的一部分,。

下面就是本文例子的配置文件rules.xml。有幾點必須說明,。

首先,,模式可以用兩種方式指定:或者使用<pattern>元素,或者通過代表規(guī)則的XML元素的屬性,。這兩種辦法可以混合使用,,且<pattern>元素是可以嵌套的。其次,,<alias>元素和<set-properties-rule>一起使用,,用來把XML屬性映射到Bean屬性。最后,,就當(dāng)前發(fā)行的Digester軟件包而言,,我們不能在配置文件中指定BeanPropertySetterRule,正如前面所介紹的,,我們用CallMethodRule來達到同樣的目標(biāo),。

<?xml version="1.0"?>
                        <digester-rules>
                        <object-create-rule pattern="catalog" classname="Catalog" />
                        <set-properties-rule pattern="catalog" >
                        <alias attr-name="library" prop-name="library" />
                        </set-properties-rule>
                        <pattern value="catalog/book">
                        <object-create-rule classname="Book" />
                        <call-method-rule pattern="author" methodname="setAuthor"
                        paramcount="0" />
                        <call-method-rule pattern="title" methodname="setTitle"
                        paramcount="0" />
                        <set-next-rule methodname="addBook" />
                        </pattern>
                        <pattern value="catalog/magazine">
                        <object-create-rule classname="Magazine" />
                        <call-method-rule pattern="name" methodname="setName" paramcount="0" />
                        <pattern value="article">
                        <object-create-rule classname="Article" />
                        <set-properties-rule>
                        <alias attr-name="page" prop-name="page" />
                        </set-properties-rule>
                        <call-method-rule pattern="headline" methodname="setHeadline"
                        paramcount="0" />
                        <set-next-rule methodname="addArticle" />
                        </pattern>
                        <set-next-rule methodname="addMagazine" />
                        </pattern>
                        </digester-rules>

現(xiàn)在,所有實際的操作都轉(zhuǎn)移到了Digester和DigesterLoader類,,XmlRulesDriver類就變得相當(dāng)簡單,。運行下面的XmlRulesDriver時,在第一個命令行參數(shù)中指定目錄文檔的名字,,在第二個參數(shù)中指定rules.xml(注意,,DigesterLoader不是從File或者org.xml.sax.InputSource讀取rules.xml文件,而是要求指定一個URL,,因此,,下面代碼中File引用被轉(zhuǎn)換成了等價的URL),。

import org.apache.commons.digester.*;
                        import org.apache.commons.digester.xmlrules.*;
                        import java.io.*;
                        import java.util.*;
                        public class XmlRulesDriver {
                        public static void main( String[] args ) {
                        try {
                        File input = new File( args[0] );
                        File rules = new File( args[1] );
                        Digester digester = DigesterLoader.createDigester( rules.toURL() );
                        Catalog catalog = (Catalog)digester.parse( input );
                        System.out.println( catalog.toString() );
                        } catch( Exception exc ) {
                        exc.printStackTrace();
                        }
                        }
                        }

結(jié)束語:本文對Jakarta Commons Digester的介紹就到這里結(jié)束。當(dāng)然,,還有許多內(nèi)容這里尚未涉及,。其中一個在這里忽略的主題是XML名稱空間:Digester允許把規(guī)則定義成只能對某一個名稱空間內(nèi)定義的元素起作用。

另外,,我們簡單地提及了通過擴展Rule類開發(fā)定制規(guī)則的問題,。按照習(xí)慣,Digester類提供了push(),、peek()和pop()方法,,使得開發(fā)者能夠自由地直接操作解析棧。

參考:

Jakarta Commons Digester Homepage

Jakarta Struts Homepage

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多