科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件使用Jakarta Digester轻松处理和解析XML

使用Jakarta Digester轻松处理和解析XML

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Jakarta的Digester组件为解析一个XML文件提供一个基于规则的直观框架,对它进行编程比给标准的基于SAX的API编程要容易得多。

作者:builder.com.cn 2007年2月5日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

列表D

public class LibraryRuleSet {

public static LibraryDetailsConfiguration getLibraryDetailsConfig (String libraryConfigFilePath) {

LibraryDetailsConfiguration libraryDetails = null;

try {

Digester digester = new Digester();

digester.setValidating(false);

// create an object of the given class,

//push it to top of Digester object stack

digester.addObjectCreate("library",LibraryDetailsConfiguration.class);

digester.addObjectCreate("library/movie", MovieDetailsConfiguration.class);

// call the setter method of the given bean property on the object

digester.addBeanPropertySetter("library/movie/title","title");

digester.addBeanPropertySetter("library/movie/rating","rating");

// pop the object on top of the stack

digester.addSetNext("library/movie","setMovie");

// begin parsing

File fileObj = new File(libraryConfigFilePath);

libraryDetails = (LibraryDetailsConfiguration) digester.parse(fileObj);

} catch(Exception e) {

System.out.println("Exception in parsing data file: " + e);

e.printStackTrace();

}

return libraryDetails;

}

}

这个类实际执行的工作包括:解析XML数据,并把这些数据映射到前面定义的Java对象中。首先,addObjectCreate()方法建立两个Configuration类实例;接下来,addBeanPropertySetter()方法告诉Digester调用哪个设置方法(setter method)将<title>和<rating>元素的字符数据附加到对象实例上;最后,parse()方法对文件进行解析和执行确定的行动。最终得到的结果是LibraryDetailsConfiguration类的一个适当配置的实例。现在,只需要写一个小存根,它将调用那个实例的printLibraryDetails()方法。(列表E

列表E

public class TestDigester

{

public static void main(String args[]) {

LibraryDetailsConfiguration libraryDetails = LibraryRuleSet.getLibraryDetails("");

libraryDetails.printLibraryDetails();

}

}

Here's the output:

 

Minority Report -> 5Mission: Impossible III -> 3The Matrix -> 5

修改规则集

在Digester(任何基于SAX的API也一样)中,改变输出要求必须改变XML-Java对象映射,因此所使用的规则集也随之改变。为说明这一点,我们先建立一个稍微不同的XML文件,如列表F所示。

列表F

<?xml version='1.0'?>

<library>

<movie>

<title>The Matrix</title>

<cast>

<person>Keanu Reeves</person>

<person>Laurence Fishburne</person>

<person>Carrie-Anne Moss</person>

</cast>

<rating>5</rating>

</movie>

<movie>

<title>Mission: Impossible III</title>

<cast>

<person>Tom Cruise</person>

<person>Ving Rhames</person>

<person>Laurence Fishburne</person>

</cast>

<rating>3</rating>

</movie>

<movie>

<title>Minority Report</title>

<cast>

<person>Tom Cruise</person>

<person>Max von Sydow</person>

</cast>

<rating>5</rating>

</movie>

</library>

 

我们还假设你希望以不同的方法处理这些XML数据,这次以演员姓名为关键元素,并列举这名演员的所有电影。为达到这一目的,需要对MovieDetailsConfiguration类进行修改,现在我们需要一个数组来保存每部电影的演职员信息。(列表G

列表G

public class MovieDetailsConfiguration{

 

private String title;

private ArrayList movieCastList;

private int rating;

public MovieDetailsConfiguration() {

movieCastList = new ArrayList();

}

 

public void setTitle(String title) {

this.title = title;

}

 

public String getTitle() {

return title;

}

 

public void setMovieCastList(ArrayList movieCastList) {

this.movieCastList = movieCastList;

}

 

public ArrayList getMovieCastList() {

return movieCastList;

}

 

public void addMovieCast(String castName) {

movieCastList.add(castName);

}

 

public void setRating(int rating) {

this.rating = rating;

}

 

public int getRating() {

return rating;

}

}

 

还有必要修改LibraryDetailsConfiguration类的setMovie()和printLibraryDetails()方法,如列表H所示。

列表H

public class LibraryDetailsConfiguration{

private HashMap movieDetailsMap;

// movieDetailsMap would store the title as key and

// MovieDetailsConfiguration object as value

public LibraryDetailsConfiguration() {

movieDetailsMap = new HashMap();

}

public void setMovieDetailsMap(HashMap movieDetailsMap) {

this.movieDetailsMap = movieDetailsMap;

}

public HashMap getMovieDetailsMap() {

return movieDetailsMap;

}

 

public void setMovie(MovieDetailsConfiguration movieDetails) {

ArrayList movieDetailList = null;

ArrayList movieCastList = movieDetails.getMovieCastList();

Iterator itMovieCast = movieCastList.iterator();

 

while (itMovieCast.hasNext()) {

String movieCastName = (String)itMovieCast.next();

if(movieDetailsMap.containsKey(movieCastName)) {

movieDetailList = (ArrayList)

movieDetailsMap.get(movieCastName);

} else {

movieDetailList = new ArrayList();

}

 

movieDetailList.add(movieDetails);

movieDetailsMap.put(movieCastName, movieDetailList);

}

}

 

public void printLibraryDetails() {

Collection movieCastColl = this.movieDetailsMap.keySet();

if (movieCastColl != null) {

Iterator itMovieCast = movieCastColl.iterator();

while(itMovieCast.hasNext()) {

String movieCastName =(String)itMovieCast.next();

System.out.println("ACTOR: " + movieCastName);

ArrayList movieDetailsList = (ArrayList)movieDetailsMap.get(movieCastName);

Iterator itMovieDetailsList = movieDetailsList.iterator();

while (itMovieDetailsList.hasNext()) {

MovieDetailsConfiguration movieDetails = (MovieDetailsConfiguration)itMovieDetailsList.next();

System.out.println("\t\tMOVIE TITLE: " + movieDetails.getTitle());

}

}

} else {

System.out.println("Movie details do not exist");

}

}

}

 

最后,还需要修改规则集,找到并定位演职员成员,把他们附加到演职员数组上。(列表I

列表I

public class LibraryRuleSet {

public static LibraryDetailsConfiguration getLibraryDetailsConfig (String libraryConfigFilePath) {

LibraryDetailsConfiguration libraryDetails = null;

try {

Digester digester = new Digester();

digester.setValidating(false);

// create an object of the given class, push it to top of Digester object stack

digester.addObjectCreate("library",LibraryDetailsConfiguration.class);

digester.addObjectCreate("library/movie", MovieDetailsConfiguration.class);

// call the setter method of the given bean property on the object

digester.addBeanPropertySetter("library/movie/title","title");

digester.addBeanPropertySetter("library/movie/rating","rating");

 

// call the given method on the object, specify parameters

digester.addCallMethod("library/movie/cast/person", "addMovieCast",1);

digester.addCallParam("library/movie/cast/person",0);

// pop the object on top of the stack

digester.addSetNext("library/movie","setMovie");

// begin parsing

File fileObj = new File(libraryConfigFilePath);

libraryDetails = (LibraryDetailsConfiguration) digester.parse(fileObj);

} catch(Exception e) {

System.out.println("Exception in parsing movie data: " + e);

e.printStackTrace();

}

return libraryDetails;

}

}

以下是修改后的printLibraryDetails()方法输出结果:

ACTOR: Carrie-Anne Moss

MOVIE TITLE: The Matrix

ACTOR: Keanu Reeves

MOVIE TITLE: The Matrix

ACTOR: Laurence Fishburne

MOVIE TITLE: The Matrix

MOVIE TITLE: Mission: Impossible III

ACTOR: Ving Rhames

MOVIE TITLE: Mission: Impossible III

ACTOR: Tom Cruise

MOVIE TITLE: Mission: Impossible III

MOVIE TITLE: Minority Report

ACTOR: Max von Sydow

MOVIE TITLE: Minority Report

将规则集保存为XML

在前面的例子中,你看到用Java编写的Digester规则集。但是,Digester最大的优点在于,这并不是将XML元素映射到行动的唯一定义模式。而且,你还可以用XML指定规则集,这使得非Java开发人员也有可能利用Digester的强大功能。

为说明这个问题,我们首先删除在前面例子中定义的LibraryRuleSet类,再用以XML编写的规则集来代替它,如列表J所示。

列表J

<?xml version='1.0'?>

<digester-rules>

<pattern value="library">

<object-create-rule classname="sample.config.LibraryDetailsConfiguration"/>

</pattern>

<pattern value="library/movie">

<object-create-rule classname="sample.config.MovieDetailsConfiguration"/>

<bean-property-setter-rule pattern="title"/>

<call-method-rule pattern="cast/person" methodname="addMovieCast" paramcount="1" />

<call-param-rule pattern="cast/person" paramnumber="0"/>

<set-next-rule methodname="setMovie" />

</pattern>

</digester-rules>

把这个文件保存为movieRules.xml。

接下来,对存根进行修改,使它知道阅读这些XML规则集。(列表K

列表K

public class TestDigester {

public static void main(String args[]) {

TestDigester digesterClient = new TestDigester();

digesterClient.digest();

}

public void digest() {

try {

//Create Digester using rules defined in movieRules.xml

Digester digester = DigesterLoader.createDigester(this.getClass().getClassLoader().getResource("movieRules.xml"));

 

//Parse movie.xml using the Digester to get an instance of Academy

LibraryDetailsConfiguration libraryConfig = (LibraryDetailsConfiguration) digester.parse(this.getClass().getClassLoader().getResourceAsStream("movie.xml"));

libraryConfig.printLibraryDetails();

} catch(Exception e) {

System.out.println("Exception while parsing the data file : " + e);

e.printStackTrace();

}

}

}

现在,试着运行上面的代码——输出结果应该与前面的例子相同。

如这些例子所说明的,Jakarta的Digester组件为解析一个XML文件提供一个基于规则的直观框架,对它进行编程比给标准的基于SAX的API编程要容易得多。使用基于XML的规则集进一步提高了可用性,允许非Java开发人员也能应用这个应用程序。自己试用一下吧——编码快乐!

责任编辑:德东

查看本文国际来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章