欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-07 22:46:34
...
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);	
 

 

 

 

相关标签: DOM4J