在java中解析xml有现成的包提供方法,常用的有四类:Dom,JDom,Sax以及Dom4j。其中前者是java中自带的,后三者需要大家从开源诸如sourceforge这样的网站下载jar包,然后在eclipse中“build path”加载外来的jar文件就行。各自的入门demo可以观看官网文档,听说文档有点晦涩难懂,可以多多google之,园子里有的是资源。接下来主要讲的是如何使用Dom4j解析xml文档。

1、什么是xml

  首先从维基百科里盗图一张,解释xml的主要结构——『节点(node):节点名称和节点值。』,『属性(attribute):属性名称和属性值。』。

  上图中第一行解释了该xml文件的版本信息,这在写入xml文件的时候需要注明,有时候还需要注明文件的编码方式例如“utf-8”。在每一个xml文件中都有一个根节点,所有节点数据都是包含在根节点中,例如本xml文档中的根节点名称为quiz。quiz根节点下有一个名称为qanda子节点,这样类似的子节点是可重复的,当然在本xml文件中根节点下只有一个直系子节点qanda,qanda节点中有一个名称为seq的属性,其属性值为“1”,在qanda中有两个子节点,第一个子节点为question,该子节点的节点值为Who was the forty-second....一堆文字,符号标签</question>标志着该节点值的结束。以此类推第二个子节点answer的节点值(节点内容)为William....,后面<!--....>里面的内容是注释,类似html文件中的注释信息。

  对xml语言有更多兴趣的可去w2school网站文档学习。

2、开始实战

2.1 准备材料

  以下是我的xml文档示例,目的是了解xml文档的结构(完整文档见“下载我吧~”):

  上面的截图中,第一个文件ccms_position.xml文件就是传说中的标记语言,常用语web service中数据的传输,在eclipse中xml文件有两种展示方式(以上展示的是Source源文件模式),它为了让程序员方便的解析和编写xml文件特意设计的Design模式真的很人性化(自行在eclipse中打开xml文件就可以切换Design模式)。

2.2 测试结果分析

  上面的XmlDemo和XmlTest分别是demo和测试文件,所有代码如下:

 package com.xml;

 import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* @author 吴荧
*
* 解析XML文档
*/ public class XmlDemo{ public void parseXml(String inputName, String outputName) { File inputXml = new File(inputName);
SAXReader saxReader = new SAXReader(); try {
//新建输出文件
FileWriter writer = new FileWriter(outputName);
//读取XML文件,获取document对象
Document document = saxReader.read(inputXml);
//获取根节点msgData元素对象
Element msgData = document.getRootElement(); //获取根节点下的子节点strPhoneNO以及该节点名称的内容并写入文件
Element strPhoneNO = msgData.element("strPhoneNO");
String strPhoneNO_text = strPhoneNO.getTextTrim();
writer.write(strPhoneNO_text + ","); //获取根节点下的子节点PositionData
Element PositionData = msgData.element("PositionData");
String PositionData_text = PositionData.getTextTrim();
writer.write(PositionData_text + ","); //在PositionData中迭代第一层子节点
for (Iterator i = PositionData.elementIterator(); i.hasNext();){ Element node1 = (Element) i.next();
//将第一层子节点中的文字写入文本
writer.write(node1.getTextTrim());
if (i.hasNext()){
writer.write(",");
} //第一层子节点中再次遍历第二层子节点
for (Iterator j = node1.elementIterator(); j.hasNext();){ Element node2 = (Element) j.next();
//将第二层子节点中的文字写入文本
writer.write(node2.getTextTrim());
if (j.hasNext()){
writer.write(",");
} //第二层子节点中再次遍历第三层子节点
for (Iterator k = node2.elementIterator(); k.hasNext();){ Element node3 = (Element) k.next();
//将第三层子节点中的文字写入文本
writer.write(node3.getTextTrim());
if (k.hasNext()){
writer.write(",");
}
}
}
} writer.close();
} catch (DocumentException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View XmlDemo.java

 package com.xml;

 /*
* 测试代码
*/ public class XmlTest { public static void main(String [] args) {
String inputName = "src/com/xml/ccms_position.xml";
String outputName = "src/com/xml/ccms_out.txt"; XmlDemo demo4 = new XmlDemo();
demo4.parseXml(inputName, outputName);
}
}

View XmlTest.java

  上面的代码注释已经是非常详细了,其中的语法主要参考的是这篇博文,但是写入的结果并不如人意,如下图所示:

  写入文件的目的:希望解析xml文档中的所有数据,并将数据按不同字段用逗号分割符分开存入文本。

  目前代码存在的问题:

2.2.1 每遍历一个层结束以后,使用i.hasNext()方法判断是都还有下一个节点的时候被写入一个逗号,但是遇到下一个节点中是子节点而没有节点内容的时候不应该写入数据,否则就会出现第二行输出的两个逗号之间没有数据;

2.2.2 看样本中nSec节点中的内容0与nApdMsg节点中的内容8没有使用逗号分隔符分隔,考虑到也是使用i.hasNext方法的问题,应该考虑该节点的母节点遍历结束以后都要使用逗号分隔。

2.3 调试代码

  更改逗号写入条件:当前同一层节点的内容用逗号分隔;当该层循环结束,若下层节点中无文本内容只有子节点的时候不写入逗号,仅当节点有文本内容的时候才将内容写入文本并使用逗号分隔。

  在每一层循环中写入以下判断条件再写入:

 if (!nodei.getTextTrim().equals("")){
writer.write(nodei.getTextTrim());
if (i.hasNext()){
writer.write(",");
}
}

解决了了2.2.1的问题,但是2.2.2的问题仍然没有解决,只能手动在第一层写入数据之前加入逗号,感觉代码好low啊。

2.4 优化代码

2.4.1 代码中存在大量的重复块,可以将重复块写入方法调用

 public Element condition(FileWriter writer, Iterator m) throws IOException {

         Element node = (Element) m.next();
//将第一层子节点中的文字写入文本
String text = node.getTextTrim();
if (!text.equals("")){
writer.write(node.getTextTrim());
if (m.hasNext()){
writer.write(",");
}
}
return node;
}

2.5 看看其他的算法

2.5.1 Dom

2.5.2 Sax

2.5.3 JDom

挖个坑,先把jar包的资源扔出来~

java实战之解析xml的更多相关文章

  1. Java用SAX解析XML

    要解析的XML文件:myClass.xml <?xml version="1.0" encoding="utf-8"?> <class> ...

  2. JAVA使用SAX解析XML文件

    在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...

  3. java使用sax解析xml

    目的:解析xml文件,并存入mysql,并且要解析的字段能一一对应.这里解析的是微博的文件,想要利用里面的article和person_id字段. 思路: 为了能得到person_id和article ...

  4. Java 创建过滤器 解析xml文件

    今天写了一个过滤器demo,现在是解析actions.xml文件,得到action中的业务规则:不需要导入任何jar包 ActionFilter过滤器类: package accp.com.xh.ut ...

  5. 【java】:解析xml

    ==========================================xml文件<?xml version="1.0" encoding="GB231 ...

  6. JAVA通过XPath解析XML性能比较(原创)

    (转载请标明原文地址) 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 XML文件解析的4种方法 通常解析XML文件有四种经典的方法.基本的解析方式有两种 ...

  7. java使用dom4j解析xml文件

    关于xml的知识,及作用什么的就不说了,直接解释如何使用dom4j解析.假如有如下xml: dom4j解析xml其实很简单,只要你有点java基础,知道xml文件.结合下面的xml文件和java代码, ...

  8. 【收藏用】--切勿转载JAVA 使用Dom4j 解析XML

    原帖地址 : http://blog.csdn.NET/yyywyr/article/details/38359049 解析XML的方式有很多,本文介绍使用dom4j解析xml. 1.环境准备 (1) ...

  9. Java是如何解析xml文件的(DOM)

    Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX ...

随机推荐

  1. drop和delete的区别是什么

    当你不再需要该表时, 用 drop;当你仍要保留该表,但要删除所有记录时, 用 truncate;当你要删除部分记录时(always with a WHERE clause), 用 delete.

  2. lumen Console Commands

    1.在app->Console->Commands中新增类 继承  Illuminate\Console\Command <?php namespace App\Console\Co ...

  3. 实战Ubuntu Server上配置LXDE+VNC环境

    1.安装x-window 使用apt-get 安装 xorg sudo apt-get install xorg 如果提示以下内容,就说明需要update下源列表,使用sudo apt-get upd ...

  4. MongoDB 常用故障排查工具

    1.profile profiling levels: 0,关闭profile:1,只抓取slow查询:2,抓取所有数据. 启动profile并且设置Profile级别: 可以通过mongo shel ...

  5. MySQL 调优基础(五) Linux网络

    1. TCP/IP模型 我们一般知道OSI的网络参考模型是分为7层:“应表会传网数物”——应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.而实际的Linux网络层协议是参照了OSI标准,但 ...

  6. SQL Server调优系列基础篇(并行运算总结篇二)

    前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...

  7. strlen和sizeof的区别

    1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型.该类型保证能容纳实现所建立的最大对象的字节大小.   2.sizeof是算符,strlen是函 ...

  8. linux 分区 物理卷 逻辑卷

    今天我们主要说说分区.格式化.SWAP.LVM.软件RAID的创建哈~ 格式化 查看当前分区:fdisk   -l 这个命令我们以前是讲过的,我现在问下,ID那项是什么意思? 83 是代表EXT2和E ...

  9. delphi 安装.dpk;package

    打开.dpk,若要将包直接安装在delphi的默认安装目录下(D:\Program Files (x86)\Borland\Delphi7\Projects\Bpl), 可清除,点击options打开 ...

  10. KEIL MDK STM32如何建立工程

    2. 3 4 5 6 7 QQ 463431476 8 9