锁定老帖子 主题:Java基础 XML文件的解析
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-25
最后修改:2009-07-14
先做简单的代码分析: 1.由于主要是取出结点的属性 ,需要一定数据存储结构 ArrayList<DetailData> detailList = null
public class DetailData { }
问题需要简单化,一个方法只做一样事情 /** * 迭代child结点 * @param node * @param map */ public void getChild(Node node, HashMap<String, String> map) { if (node.hasAttributes()) { getAttrByNode(node, map); } if (node.hasChildNodes()) { NodeList n2 = node.getChildNodes(); for (int j = 0; j < n2.getLength(); j++) { getChild((Node) n2.item(j), map); } } }
取出每个节点的属性 /** * 得到当前结点的属性 * @param node * @param map */ public void getAttrByNode(Node node, HashMap<String, String> map) { if (node.hasAttributes()) { NamedNodeMap nnm = node.getAttributes(); int len = nnm.getLength(); for (int j = 0; j < len; j++) { Node attr = nnm.item(j); map.put(attr.getNodeName(), setValueForNull(attr.getNodeValue())); } } }
上面的递归对于下面的XML结构绝对没有问题: <?xml version="1.0" encoding='UTF-8'?> <requestSummary currentTime='' startDay='2009-12-23' endDay='2009-12-23'> <dailySummary day='2008-03-01' totalCall='298' avgResponseTime='00:05' avgRepairTime='00:35'> </dailySummary> <dailySummary day='2008-03-01' totalCall='340' avgResponseTime='00:03' avgRepairTime='00:50'> </dailySummary> </requestSummary>
但是对于下面的结构:就应付不了: <?xml version="1.0" encoding='UTF-8'?> <requestSummary currentTime='' startDay='2009-12-23' endDay='2009-12-23'> <building building='2'> <floor floorName='1'> <line lineName='N1'> <completedInfo seatNo='12' ticket='1'> <completedDetail requestTime='43223556647' requestStaffNo='H0051' requestStaffName='张三'> </completedDetail> </completedInfo> <completedInfo seatNo='13' ticket='2'> <completedDetail requestTime='43223556647' requestStaffNo='H0050' requestStaffName='小王'> </completedDetail> </completedInfo> </line> </floor> </building> </requestSummary>
在line结点下会出现多个completedInfo ,而且 building结点也会出现多个的。这样就复杂点了,但是有了上面的递归思想,我们仍然还是有办法的:
我们的思路就是需要一个数据结构,可以把completedInfo 结点为依据的记录,作为一个对象 ,完整的把它的所有属性全部存入这个对象,这个对象是DetailData ,分公共数据 buildingName ; floorName ;lineName和completedInfo(detailMap结点数据) 不过后来发现这个结构也是有问题的:数据会不正确,后来,就把completedInfo节点的父节点全部,放进HashMap中了,这样保证一个对象的Map只存储与之一致的记录
第一步,查找孩子结点及父结点
public void getChildForDetail(Node node) { if (node.hasAttributes()) { DetailData detailData = new DetailData(); // setBuildingName detailData.setBuildingName(buildingName); HashMap<String, String> detailMap = new HashMap<String, String>(); if ("completedInfo".equals(node.getNodeName())) { // 下面的代码为InProgressRequest特制------ Node parent = node.getParentNode(); String pName = parent.getNodeName(); if ("line".equals(pName)) { getParentAttr(parent,detailMap); } //为InProgressRequest特制 End----- getChildAttrByNode(node, detailMap); // setDetailMap detailData.setDetailMap(detailMap); // detailData 对象添加 detailList.add(detailData); } } if (node.hasChildNodes()) { NodeList n2 = node.getChildNodes(); for (int j = 0; j < n2.getLength(); j++) { getChildForDetail((Node) n2.item(j)); } } } 第2步:取出结点的属性
/** * 取出detailDate信息 * * @param node * 当前节点 * @param detailMap * 存储当前节点及子节点的所有属性信息 */ public void getChildAttrByNode(Node node, HashMap<String, String> detailMap) { if (node.hasAttributes()) { NamedNodeMap nnm = node.getAttributes(); int len = nnm.getLength(); for (int j = 0; j < len; j++) { Node attr = nnm.item(j); detailMap.put(attr.getNodeName(), setValueForNull(attr .getNodeValue())); } } if (node.hasChildNodes()) { NodeList n2 = node.getChildNodes(); for (int j = 0; j < n2.getLength(); j++) { getChildAttrByNode((Node) n2.item(j), detailMap); } } }
随着项目的进展后来 ,又出现了其他的情况: <?xml version="1.0" encoding='UTF-8'?> <requestSummary currentTime='' startDay='2009-12-23' endDay='2009-12-23'> <building building='2'> <floor floorName='1'> <line lineName='N1'> <completedInfo seatNo='12' ticket='1'> <completedDetail requestTime='43223556647' requestStaffNo='H0051' requestStaffName='张三'> </completedDetail> <completedDetail requestTime='43223556647' requestStaffNo='H0050' requestStaffName='小王'> </completedDetail> </completedInfo> </line> </floor> </building> </requestSummary> 关键性的节点循环的地方发生变化 同样的,都不难,我们还是可以解决!
xml解析的文件及源码 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-26
有dom4j jdom xstream digester,为什么还要自己写啊
有那时间看看 socket thread collection 都比这个实在 |
|
返回顶楼 | |
发表时间:2009-06-26
恩,是的dom4j是很方便,但是使用JDK自带的东西W3C 主要是业务需求,当解决实际问题的时候,你会发现dom4j来解决不够用,所以才自己写了个解析的 你可以解析下面的格式试验下,用Dom4j
<test currentTime='' startDay='2009-12-23' endDay='2009-12-23'> <building buildingName='1'> <floor floorName='1'> <line lineName='N1'> <completedInfo seatNo='11' responseTime='11:25' RepairTime='11:23'> <completedDetail requestTime='11:23' requestStaffNo='H0050' requestStaffName='张三' responseTime='11:25' responseStaffNo='J332' responseStaffName='李四' completeTime='11:50' completeStaffNo='Y6500' completeStaffName='梁五'> </completedDetail> </completedInfo> <completedInfo seatNo='12' responseTime='11:25' RepairTime='11:23'> <completedDetail requestTime='11:23' requestStaffNo='H00501' requestStaffName='张三1' responseTime='11:25' responseStaffNo='J3321' responseStaffName='李四1' completeTime='11:50' completeStaffNo='Y65001' completeStaffName='梁五1'> </completedDetail> </completedInfo> </line> </floor> </building> < /test > 如果解析出来了,把代码贴出来看哈,O(∩_∩)O谢谢指教 |
|
返回顶楼 | |
发表时间:2009-06-26
最后修改:2009-06-26
LZ和我的初衷一样,我也写过一个基于W3C DOM的XML2Object,Object2XML的工具,互相学习。
传送门:依旧简单的小工具XMLUtil |
|
返回顶楼 | |
发表时间:2009-06-26
jomper 写道 LZ和我的初衷一样,我也写过一个基于W3C DOM的XML2Object,Object2XML的工具,互相学习。
传送门:依旧简单的小工具XMLUtil O(∩_∩)O谢谢,呵呵,是啊,这个解析是我和师傅一起研究了到晚上2点,才出来的。 不容易啊 ,终于有人和我有一样的初衷 |
|
返回顶楼 | |
发表时间:2010-06-10
|
|
返回顶楼 | |
浏览 7414 次