`
lige239141
  • 浏览: 174925 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

从Digester解析xml说起

    博客分类:
  • ssh
阅读更多

想弄清楚struts1到底是怎么解析struts-config.xml文件。于是在源代码中发现用的是apache的Digester库。第一次接触这个,于是好好的查阅了一番。

下面的代码,是从http://soft901.iteye.com/blog/335452上面弄过来的,自己改造了一下,只为了自己更清楚的理解。

待读取的XML文件datasource.xml: 

 

<?xml version="1.0"?>
<datasources>
	<datasource>
		<name>mysqldatasource</name>
		<driver>com.jdbc.mysql.Driver</driver>
		<url>jdbc:mysql://localhost:3306/test</url>
		<username>root</username>
		<password>1234</password>
	</datasource>
	<datasource>
		<name>oracledatasource</name>
		<driver>oracle.jdbc.driver.oracledriver</driver>
		<url>jdbc:oracle:thin:@localhost:1521:orcl</url>
		<username>scott</username>
		<password>tiger</password>
	</datasource>
</datasources>

 此xml文件分2层结构,分别为: 

 

<datasources>节点 其下包含2个<datasource>节点 
<datasource>节点,其下包含各种信息节点 : 如:<name> 、<url>等。 
我们的操作目标是把datasource中的信息节点的内容提取出来。 
把每个<datasource>看做为一个对象,<datasource>中信息节点的内容为对象中的元素。

设定一个类DatasourceConfig.java 其内容如下: 

 

package xmlParse.digester;

public class DataSourceConfig {
	private String name;
	private String driver;
	private String url;
	private String username;
	private String password;

	public String getName() {
		return name;
	}

	public String getDriver() {
		return driver;
	}

	public String getUrl() {
		return url;
	}

	public String getUsername() {
		return username;
	}

	public String getPassword() {
		return password;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	 public String toString() {  
	        return "DataSource : " + "name : " + name + " Driver : " + driver  
	                + " URL : " + url + " Username : " + username + " Password : "  
	                + password;  
	 }  
}

 

其中设置解析的rule规则的方法有四种,一一列出代码。

 

第一种 使用addCallMethod方法,映射XML所对应的节点与这个Call method的参数即可,这个call method将读取的一个标签内所有的值存入对象,然后再存入一个集合中。

 

 

package xmlParse.digester;
/**
 * 利用digester来解析xml.
 */
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

public class DigesterParseTest {
	private List<DataSourceConfig> dataSources;

	public static void main(String[] args) {
		DigesterParseTest sd = new DigesterParseTest();
		sd.digester();
		System.out.println(sd.toString());
	}

	void digester() {
		Digester digester = new Digester();
		setDataSources(new ArrayList<DataSourceConfig>());
		// 把当前对象压入到digester栈中。
		digester.push(this);
		/* 设定解析此xml文件的规则 */
		// 将XML文件解析所对应的方法.this.addDataSource();参数个数为5个.
		digester.addCallMethod("datasources/datasource", "addDataSource", 5);
		digester.addCallParam("datasources/datasource/name", 0);
		digester.addCallParam("datasources/datasource/driver", 1);
		digester.addCallParam("datasources/datasource/url", 2);
		digester.addCallParam("datasources/datasource/username", 3);
		digester.addCallParam("datasources/datasource/password", 4);

		try {
			digester.parse("config/datasource.xml");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}
	
	public void addDataSource(final String name, final String driver,
			final String url, final String username, final String password) {
		DataSourceConfig dataSource = new DataSourceConfig();
		dataSource.setName(name);
		dataSource.setDriver(driver);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		getDataSources().add(dataSource);
	}
	
	public List<DataSourceConfig> getDataSources() {
		return dataSources;
	}

	public void setDataSources(List<DataSourceConfig> dataSources) {
		this.dataSources = dataSources;
	}

	public String toString() {
		String newline = System.getProperty("line.separator");
		StringBuffer buff = new StringBuffer();
		if (getDataSources() != null) {
			for (DataSourceConfig ds : getDataSources()) {
				buff.append(newline).append(ds);
			}
			return buff.toString();
		}
		return "";
	}
}

 

 

第二种 使用addObjectCreate方法,创建对象映射XML文件的属性对java Bean. 读取完一个对象将对象加入到一个集合中,然后再读取XML文件的下一个标签: 

 

package xmlParse.digester;
/**
 * 利用digester来解析xml.
 */
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

public class DigesterParseTest2 {
	private List<DataSourceConfig> dataSources;

	public static void main(String[] args) {
		DigesterParseTest sd = new DigesterParseTest();
		sd.digester();
		System.out.println(sd.toString());
	}
	private void digester() {
		Digester digester = new Digester();
		setDataSources(new ArrayList<DataSourceConfig>());
		// 把当前对象压入到digester栈中。
		digester.push(this);
		
		/* 设定解析此xml文件的规则 */
		digester.addObjectCreate("datasources/datasource", DataSourceConfig.class);
		
		//效果跟addSetProperties一样
//		digester.addBeanPropertySetter("datasources/datasource/name","name");
//		digester.addBeanPropertySetter("datasources/datasource/driver", "driver");
//		digester.addBeanPropertySetter("datasources/datasource/url", "url");
//		digester.addBeanPropertySetter("datasources/datasource/username", "username");
//		digester.addBeanPropertySetter("datasources/datasource/password", "password");
		digester.addSetProperties("datasources/datasource/name");
		digester.addSetProperties("datasources/datasource/driver");
		digester.addSetProperties("datasources/datasource/url");
		digester.addSetProperties("datasources/datasource/username");
		digester.addSetProperties("datasources/datasource/password");
		digester.addSetNext("datasources/datasource", "addDataSource");
		try {
			digester.parse("config/datasource.xml");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}
	
	public void addDataSource(final DataSourceConfig datasource){
		getDataSources().add(datasource);
	}
	public List<DataSourceConfig> getDataSources() {
		return dataSources;
	}

	public void setDataSources(List<DataSourceConfig> dataSources) {
		this.dataSources = dataSources;
	}

	public String toString() {
		String newline = System.getProperty("line.separator");
		StringBuffer buff = new StringBuffer();
		if (getDataSources() != null) {
			for (DataSourceConfig ds : getDataSources()) {
				buff.append(newline).append(ds);
			}
			return buff.toString();
		}
		return "";
	}
}

 

 

第三种:使用addRule方法来解析datasource.xml: 

 

private void digester() {
	Digester digester = new Digester();

	setDataSources(new Vector<DataSource>());
	// 把当前对象压入到digester栈中。
	digester.push(this);

	Rule objectCreate = new ObjectCreateRule(DataSource.class);
	digester.addRule("datasources/datasource", objectCreate);

	digester.addRule("datasources/datasource", new SetNextRule(
			"addDataSource"));

	digester.addRule("datasources/datasource/name", new CallMethodRule(
			"setName", 0, new Class[] { String.class }));
	digester.addRule("datasources/datasource/driver", new CallMethodRule(
			"setDriver", 0, new Class[] { String.class }));
	digester.addRule("datasources/datasource/url", new CallMethodRule(
			"setUrl", 0, new Class[] { String.class }));
	digester.addRule("datasources/datasource/username", new CallMethodRule(
			"setUsername", 0, new Class[] { String.class }));
	digester.addRule("datasources/datasource/password", new CallMethodRule(
			"setPassword", 0, new Class[] { String.class }));
	try {
		digester.parse("datasource.xml");
	} catch (IOException e) {
		e.printStackTrace();
	} catch (SAXException e) {
		e.printStackTrace();
	}
}

 

 

第四种:把规则写在xml文件中。新建rules.xml

 

<? xml version = " 1.0 " ?>
<digester-rules>
	<object-create-rule pattern=" datasources "
		classname=" datasources " />
	<pattern value=" datasources/datasource ">
		<object-create-rule classname=" datasource " />
		<call-method-rule pattern=" name " methodname=" setName "
			paramcount=" 0 " />
		<call-method-rule pattern=" driver " methodname=" setDriver "
			paramcount=" 0 " />
		<call-method-rule pattern=" url " methodname=" setUrl "
			paramcount=" 0 " />
		<call-method-rule pattern=" username " methodname=" setUsername "
			paramcount=" 0 " />
		<call-method-rule pattern=" password " methodname=" setPassword "
			paramcount=" 0 " />
		<set-next-rule methodname=" addDatasource " />
	</pattern>
	
</digester-rules>

 

digester方法如下:

 

private void digester() {
		setDataSources(new ArrayList<DataSourceConfig>());
		try {
			File rules = new File("config/rules.xml");
			//创建digester对象并指定解析规则
			Digester digester = DigesterLoader.createDigester(rules.toURL());
			digester.parse("config/datasource.xml");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}

 

以上是digester四种解析xml的方法。这些例子只是些直观的说明。竹笋炒肉的三篇有关digester的笔记更深入一步的讲解了有关digester的知识。链接见下:

digester学习笔记1

digester学习笔记2

digester学习笔记3

另附上commons-digester-2.0 API官网

 

回到文章开头说的,其实了解digester是为了弄明白struts怎么解析配置文件的。本来想自己整理下,但是发现struts学习--初始化MoudleConfig 正好解释的很清楚,只以解析DataSourceConfig标签为例稍微补充下RuleSet配置说明。

通过ActionServlet的成员变量configDigester的初始化来深入理解struts-config.xml文件的加载,其中配置信息可以通过org.apache.struts.config.impl.ModuleConfigImpl类描述。 

configDigester上注册了RuleSet类为ConfigRuleSet,主要通过覆盖方法public void addRuleInstances(Digester digester)来为digester注册Rule,代码分析如下: 

1.处理ModuleConfigImpl对象中的数据源DataSourceConfig对象: 
/* 1.1当遇到struts-config/data-sources/data-source开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.DataSourceConfig对象,并入栈;遇到结束标记时对象出栈。*/ 

digester.addObjectCreate 
("struts-config/data-sources/data-source", "org.apache.struts.config.DataSourceConfig", "className"); 
/*1.2 当遇到struts-config/data-sources/data-source开始标记时根据data-source标记的属性设置栈顶元素对象的属性 */ 
digester.addSetProperties 
("struts-config/data-sources/data-source"); 

/*1.3 遇到struts-config/data-sources/data-source结束标记时将调用次栈顶元素ModuleConfigImpl对象的addDataSourceConfig方法,将当前栈顶元素DataSourceConfig对象为值,struts-config/data-sources/data-source标记的key属性为键推入到ModuleConfigImpl的HashMap类型成员变量dataSources中。*/ 
digester.addSetNext 
("struts-config/data-sources/data-source", "addDataSourceConfig", "org.apache.struts.config.DataSourceConfig"); 

/*1.4 将遇到的set-property标记的property属性值为key,value属性值为值添加到栈顶DataSourceConfig对象的HashMap类型成员变量properties中。*/ digester.addRule 
("struts-config/data-sources/data-source/set-property", new AddDataSourcePropertyRule()); 
分享到:
评论

相关推荐

    利用commons-digester解析xml

    标题“利用commons-digester解析XML”涉及到的是Java开发中的一种处理XML文档的工具——Apache Commons Digester。这个库提供了一种方便的方式来映射XML文档结构到Java对象,从而简化了XML数据的处理过程。 Apache ...

    digester解析xml的问题.pdf

    Digester 是 Apache Commons 中的一个工具类库,它用于解析 XML 文档,并根据预先定义的规则自动创建和配置 Java 对象。在上述问题中,我们看到一个 XML 文档表示了一个考试,其中包含了多个题目,每个题目有其编号...

    digester解析xml必备包.rar

    2. **设置解析器**:将XML解析器(如SAXParser)与Digester关联,以便在解析XML时触发已设定的规则。 3. **解析XML**:使用`parse`方法,传入XML文件的输入流,开始解析过程。 4. **处理结果**:解析完成后,根...

    Digester解析XML文件

    本文将深入探讨如何使用Digester解析XML文件,以及在实际项目中如何应用。 首先,让我们了解什么是Apache Commons Digester。这是一个Java库,它的主要功能是读取XML文件,并基于一系列预先定义的规则(Rule),...

    使用Digester解析XML文档示例

    ### 使用Digester解析XML文档示例 #### 一、Digester简介与应用场景 Digester是Apache Jakarta项目下的一个工具类库,它简化了基于SAX(Simple API for XML)的XML解析过程。Digester能够根据定义好的规则自动将...

    Digester解析XML

    ### Digester解析XML知识点详解 #### 一、Digester简介 **Digester** 是Apache Commons项目中的一个子项目,主要用于简化XML文档的解析工作。它建立在SAX的基础之上,通过定义一系列的模式(Pattern)和规则(Rule...

    digester解析XML文件实例

    这个"digester解析XML文件实例"是一个很好的学习资源,帮助开发者理解如何在实际项目中运用Digester。 首先,我们要了解Digester的基本工作原理。Digester通过定义一系列规则(Rules),当解析到XML文档中特定的...

    org.apache.commons.digester解析XML.rar

    Apache Commons Digester是一个Java库,专门用于将XML文档解析成对象结构。这个“org.apache.commons.digester解析XML.rar”压缩包包含了一个测试工程,它演示了如何使用Digester库来解析XML文件并映射到Java对象上...

    Digester解析XML的小例子(对象嵌套)

    这都是通过 Digester 的强大功能实现的,它可以帮助开发者快速地从XML配置文件中构建和配置复杂的Java对象结构,而无需手动解析XML。 总结来说,Digester是STRUTS框架中用于XML解析的利器,它通过规则匹配的方式,...

    使用Apache的Digester来解析XML文档

    Apache Digester是一个强大的Java库,专门用于将XML文档解析成对象模型。在处理XML到Java对象映射时,它提供了一种简洁的方式,避免了手动编写大量繁琐的XML解析代码。这个工具尤其适用于那些需要频繁从XML配置文件...

    使用digester解析XML

    不错的解析XML的类,主要利用org.apache.commons.digester.Digester;

    Digester解析XML问题.pdf

    在示例代码中, DigesterDriver演示了如何配置 Digester来解析XML文件,创建`Catalog`对象并填充其`Book`和`Magazine`子对象,以及相关的`Article`对象。每个元素的属性通过`addBeanPropertySetter()`设置,而对象...

    java反射,Digester解析xml文档

    Java反射和Digester库是Java开发中的两个重要概念,它们在处理动态代码执行和XML文档解析方面发挥着关键作用。 **Java反射** 是Java语言的一个强大特性,它允许程序在运行时检查和操作类、接口、方法和字段。通过...

    digester解析xml 所需jar包

    为了方便地解析和操作XML文档,Apache组织提供了一个名为`Digester`的工具,它是一个用于将XML文档映射到Java对象的框架。本篇文章将详细介绍如何使用`Digester`解析XML,以及在使用过程中需要的依赖库。 首先,`...

    digester解析xml

    《digester解析XML详解》 在Java开发中,XML作为一种数据交换格式,广泛应用于配置文件、数据传输等场景。为了方便地将XML文档解析为Java对象,Apache组织提供了一个名为Digester的工具库,它允许开发者通过规则来...

    Digester java解析xml

    Java中的Digester库是Apache Commons项目的一部分,它提供了一种方便的方式来解析XML文档,并将解析结果映射到Java对象模型上。这个库特别适合于创建简单的XML到Java对象的映射,而不需要编写大量的手动解析代码。在...

    digester 解析xml

    本篇文章将深入探讨如何使用Digester来解析XML,并通过XSD(XML Schema Definition)进行验证,最终将XML数据转换为Java Bean对象。 **什么是Apache Commons Digester?** Apache Commons Digester是一个Java库,它...

Global site tag (gtag.js) - Google Analytics