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);