Dom4j高级应用:遍历节点信息与实体类的存储
程序员文章站
2022-04-13 22:03:01
...
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);
上一篇: 解析中常见错误
下一篇: Java 解析XML dom4j