Dom4j高级应用:遍历节点信息与实体类的存储

katelynlily 2012-09-07

DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了Java 集合框架并完
全支持DOM,SAX 和 JAXP。 DOM4J 使用起来非常简单.只要你了解基本的 XML-DOM 模型,就能使用.
在下面的例子中,将遍历预定义好的Xml所有的节点的信息,并将取出的信息保存在实体类中.
首先,XMl定义如下:
<?xml version="1.0" encoding="UTF-8"?>
<ReportMapping>
	<Header>
		<Field>
			<name>number</name>
			<type>1</type>
			<beginRow>1</beginRow>
			<beginCell>2</beginCell>
		</Field>
			
		<Field>
			<name>date</name>
			<type>1</type>
			<beginRow>1</beginRow>
			<beginCell>5</beginCell>
		</Field>			
		
		<Field>
			<name>storeNum</name>
			<type>1</type>
			<beginRow>3</beginRow>
			<beginCell>2</beginCell>
		</Field>
		
		<Field>
			<name>remarks</name>
			<type>1</type>
			<beginRow>5</beginRow>
			<beginCell>2</beginCell>
		</Field>	
	</Header>
	
	<Body name="XXXX" startRow="10" finishRow="22" >
		<Field>
			<name>SerialNumber</name>
			<index>0</index>
			<type>0</type>
			<beginRow>1</beginRow>
			<beginCell>1</beginCell>
		</Field>
		<Field>
			<name>Name</name>
			<index>0</index>
			<type>0</type>
			<beginRow>1</beginRow>
			<beginCell>1</beginCell>
		</Field>
		<Field>
			<name>BatchNumber</name>
			<index>0</index>
			<type>0</type>
			<beginRow>1</beginRow>
			<beginCell>1</beginCell>
		</Field>
	</Body>
	<Images>
		<Image>
			<name>imageStream</name>
			<type>2</type>
			<imageInputStream>File</imageInputStream>
			<Dx1>0</Dx1>
			<Dy1>0</Dy1>
			<Dx2>0</Dx2>
			<Dy2>0</Dy2>
			<shortCol1>8</shortCol1>
			<row1>27</row1>
			<shortCol2>10</shortCol2>
			<row2>30</row2>
			</Image>
	</Images>
</ReportMapping>
 定义好的实体类  GenericField 如下:   
/**
 * @描述:这是一个实体类,用于存放文字域的数据。文字域是在 *.xml 中定义的
 * 文字域样式如下:
 * <ReportMapping>
 * 		<Header>
 * 			<Field>
 * 				<name>aaaa</name>
 * 				<type>1</type>
 * 				<beginRow>16</beginRow>
 * 				<beginCell>34</beginCell>
 * 			</Field>
 * 		</Header>
 * </ReportMapping>
 * @注明:文字域在Header(表示模板的头部分)和Footer(标识模板的脚部分)应用较多
 * @author Yangcl
 *
 */
public class GenericField 
{
	private String name;
	private int   type;
	private int   beginRow;
	private int   beginCell;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public int getBeginRow() {
		return beginRow;
	}
	public void setBeginRow(int beginRow) {
		this.beginRow = beginRow;
	}
	public int getBeginCell() {
		return beginCell;
	}
	public void setBeginCell(int beginCell) {
		this.beginCell = beginCell;
	}
}
 在上一篇文章中“利用POI在Excel文档任意单元格写入数据”,是这篇文章的铺垫.	beginRow:是你单元格的起始
行坐标,beginCell是你单元格的起始列坐标. name 这个属性在这片文章中您可以姑且理解为你要在这个单元格写入
的信息.如果向更深层次的扩展,这个name属性可以和 Map 的 Key值做匹配, 从而引入Map的Value值, 再向更深的
地方扩展您可以将 现在系统中普遍使用的一种轻量级数据交换格式:json联系起来. 将 json数据串用Gson转换成为
Map格式数据,然后在写入到Excel中. 后面的文章会提到一些关于Gson的内容,如果您有什么更好的观点, 希望您给我
留言, 我会认真接受.
下面进入正题:如何遍历和存储这些数据节点信息
package manager;

import java.io.File;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import manager.entity.BodyField;
import manager.entity.GenericField;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Report 
{
	Document document = null;
	
	Element bodyElement = null;
	
	List<GenericField>  heads = null;
	List<BodyField> 	bodys = null;

	/**
	 * @描述:遍历Xml文件的头部分
	 * 
	 * @param rootElement
	 * @return headerList
	 * 
	 * @author Yangcl
	 */
	public List<GenericField> head(Element rootElement) 
	{
		List<GenericField> headerList = new ArrayList<GenericField>(); 
		Element headerElement = rootElement.element("Header");		
		for(Iterator iter = headerElement.elementIterator();iter.hasNext();) 
		{
			Element attributeElement = (Element) iter.next();	
			// 取得Field节点下 <name>的值
			String fieldName = attributeElement.elementTextTrim("name");
			String fieldType = attributeElement.elementTextTrim("type");
			String fieldRow = attributeElement.elementTextTrim("beginRow");
			String fieldCell = attributeElement.elementTextTrim("beginCell");

			// 转换为 int类型数据
			int intFieldType = new Integer(fieldType);
			int intFieldRow = new Integer(fieldRow);
			int intFieldCell = new Integer(fieldCell);

			// 放入实体类中
			GenericField gf = new GenericField();
			gf.setName(fieldName);
			gf.setType(intFieldType);
			gf.setBeginRow(intFieldRow);
			gf.setBeginCell(intFieldCell);
			//遍历完成一个<Field>域以后,形成一个Map对象,然后存入到一个List中保存
			headerList.add(gf);
		}
		return headerList;
	}
	
	/**
	 * @描述:遍历Xml文件的body部分
	 * 
	 * @param rootElement
	 * @return bodylist
	 * 
	 * @author Yangcl
	 */
	public List<BodyField> body(Element rootElement) 
	{
		List<BodyField> bodylist = new LinkedList<BodyField>();// 存储Body所有节点
		bodyElement = rootElement.element("Body");
		// 进入<Body>,遍历重复节点
		for (Iterator iter = bodyElement.elementIterator(); iter.hasNext();) 
		{
			Map<String, Object> fieldMap = new HashMap<String, Object>();
			Element element = (Element) iter.next();
 
			// 取得Field节点下的值
			String xml_Name = element.elementTextTrim("name");
			String xml_Index = element.elementTextTrim("index");
			String xml_Type = element.elementTextTrim("type");
			String xml_Row = element.elementTextTrim("beginRow");
			String xml_Cell = element.elementTextTrim("beginCell");

			// 转换为 int类型数据
			int intFieldIndex = new Integer(xml_Index);
			int intFieldType = new Integer(xml_Type);
			int intFieldRow = new Integer(xml_Row);
			int intFieldCell = new Integer(xml_Cell);;
			
			// 放入实体类中
			BodyField bf = new BodyField();
			bf.setName(xml_Name);
			bf.setType(intFieldType);
			bf.setBeginRow(intFieldRow);
			bf.setBeginCell(intFieldCell);
			bf.setIndex(intFieldIndex);
			
			bodylist.add(bf);
		}

		return bodylist;
	}
	
	/**
	 * @描述:这个方法用于加载Xml文件,取得节点中的所有信息。
	 * 
	 * @param mappingURL
	 * 
	 * @author Yangcl
	 */
	public void loadXmlMapping(String mappingURL) 
	{	
		File xmlConfigFile = new File(mappingURL);
		SAXReader saxReader = new SAXReader();
		try {
			document = saxReader.read(xmlConfigFile);
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Element rootElement = document.getRootElement();// 获取根节点:ReportMapping
		heads = head(rootElement);
		bodys = body(rootElement);
		foots = foot(rootElement);
		image = image(rootElement); 
		
	}
}
 每个方法的是做什么的
public List<GenericField> head(Element rootElement):用于遍历Xml中<head>节点
public List<BodyField> body(Element rootElement):用于遍历Xml中的<body>节点
public void loadXmlMapping(String mappingURL):用于加载Xml,这里他是一个接口方法。在别的类中您可
以这样调用他:Report  r = new Report ()
r.loadXmlMapping("E:/work/Tamplates/config-reportMapping.xml");
在程序的代码段中,每一步定义的逻辑、目的都有比较详细的注释,在这里就不再敖述. 这些代码可以在您的成型的系统
中发挥作用, 关于测试的代码我就不贴了,您可以自己研究下. 如果有不能理解的段落, 您可以留言, 我会及时回复.
如果您想转载这篇文章, 请注明出处.

    关于如何取出<body>属性:

    //取出Body属性

//取出类型为String
String bodyName = bodyElement.attribute("name").getValue();
String aaa = bodyElement.attribute("startRow").getValue();
String bbb = bodyElement.attribute("finishRow").getValue();			

int startRow = new Integer(aaa); //强制转化为 int
int finishRow = new Integer(bbb);
 

相关推荐