Java对XML文件的解析
- 一、前言
- 二、实例分析 - DOM方式解析XML文件
- 2.1 XMLDomParseUtil - 抽象工具类
- 2.2 待解析xml文件示例
- 2.3 解析xml文件
- 2.3.1 新建一个用于存储xml文件中各节点的属性和属性值的类
- 2.3.2 解析实际节点
- 2.4 测试
一、前言
1、HTTP网络传输中的数据组织方式有三种方式:
(1)HTML方式
(2)XML方式
(3)JSON方式
今天主要讲解的是对XML文件的解析。
2、对XML文件的介绍:
xml为可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。它的文件结构中包括了节点、元素、属性和属性值,其语法规则为:
(1)开始和结束标签匹配
(2)嵌套标签不能互相嵌套
(3) 区分大小写。
3、解析XML数据的方式:
(1)DOM(org.w3c.dom):
“文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。
(2)SAX(org.xml.sax):
以事件的形式通知程序,对Xml进行解析。
(3)XMLPULL(org.xmlpull.v1):
程序以“拉取”的方式对Xml进行解析。
二、实例分析 - DOM方式解析XML文件
使用java编写以DOM方式解析某目录下的特定XML文件。
2.1 XMLDomParseUtil - 抽象工具类
定义一个Xml文件的解析工具,工具只负责取出数据,并提供一个操作数据的抽象方法。方便以后打成jar包,用的时候导包就行。
package xml.util;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* 使用Dom方式解析xml文件的工具抽象类
* @author rmling
*/
public abstract class XMLDomParseUtil {
private static final DocumentBuilderFactory factory;
static {
factory = DocumentBuilderFactory.newInstance();// 加载 factory单实例
}
public XMLDomParseUtil() {}
/**element的处理 */
public abstract Object dealElement(Element element, int index);
/**处理更深入一层的标签*/
public List<Object> dealElementInTag(Element element, String tagName) {
List<Object> ls = new ArrayList<Object>();
NodeList elements = element.getElementsByTagName(tagName);
for (int index = 0; index < elements.getLength(); index++) {
ls.add(dealElement(((Element) elements.item(index)), index));
}
return ls;
}
/** 处理最外层标签 */
public List<Object> dealElementInTag(Document document, String tagName) {
List<Object> ls = new ArrayList<Object>();
NodeList elements = document.getElementsByTagName(tagName);
for (int index = 0; index < elements.getLength(); index++) {
Element element = (Element) elements.item(index);
ls.add(dealElement(element, index));
}
return ls;
}
/** 获取document */
public static Document getDocument(String xmlPath) {
Document document = null;
try {
File file = new File(xmlPath);
if(file.exists() && file.isFile()){
InputStream inputStream = new FileInputStream(file);
//实例化一个DocumentBuilder对象
DocumentBuilder builder = factory.newDocumentBuilder();
//使用DocumentBuilder对象获取一个Document的对象
document = builder.parse(inputStream);
}else{
System.out.println("文件不存在:"+xmlPath);
}
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
}
2.2 待解析xml文件示例
<?xml version="1.0" encoding="UTF-8"?>
<process name="test" xmlns="http://jbpm.org/4.4/jpdl">
<start g="207,-11,72,48" name="start1">
<transition g="15,-10" name="to task1" to="检验任务"/>
</start>
<task candidate-groups="testCandicateGroup" g="147,50,159,52" name="检验任务">
<transition name="to judge" to="judge" g="-55,-8"/>
</task>
<decision g="202,127,48,48" name="judge">
<handler class="TeleControlDecisionHandler" />
<transition g="-36,-10" name="成功" to="检验通过任务"/>
<transition g="359,152:-31,-20" name="失败" to="检验未通过任务"/>
<transition g="108,151:38,-22" name="超时" to="超时处理任务"/>
</decision>
<task g="301,205,122,52" name="检验未通过任务">
</task>
<task g="61,202,92,52" name="超时处理任务">
</task>
<task g="151,207,151,52" name="检验通过任务">
<transition name="to success_end" to="success_end" g="-89,-10"/>
</task>
<end g="200,283,48,48" name="success_end" state="success"/>
</process>
2.3 解析xml文件
2.3.1 新建一个用于存储xml文件中各节点的属性和属性值的类
这里我们只示例解析节点及其子节点的过程:
1、新建Task实体:
/**
* 创建task标签对应的实体类
* <task candidate-groups="testCandicateGroup" g="147,50,159,52" name="检验任务">
<transition name="to judge" to="judge" g="-55,-8"/>
</task>
*/
class Task{
private String candidate_groups;
private String g;
private String name;
private List<Transition> transitions;
public Task(String candidate_groups,String g,String name,List<Transition> transitions){
this.candidate_groups = candidate_groups;
this.g = g;
this.name = name;
this.transitions = transitions;
}
public void printLog(){
if(transitions != null && transitions.size() > 0){
System.out.println(" <task candidate-groups='"+candidate_groups+"' g='"+g+"' name='"+name+"'>");
for(Transition t:transitions){
System.out.println(" <transition name='"+t.getName()+"' to='"+t.getTo()+"' g='"+t.getG()+"'/>");
}
System.out.println(" </task>");
}else{
System.out.println(" <task candidate-groups='"+candidate_groups+"' g='"+g+"' name='"+name+"'/>");
}
}
}
2、新建Transition实体:
/**
* 创建transition标签对应的实体类
* <transition name="to judge" to="judge" g="-55,-8"/>
*/
class Transition{
private String name;
private String to;
private String g;
public Transition(String name,String to,String g){
this.name = name;
this.to = to;
this.g = g;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getG() {
return g;
}
public void setG(String g) {
this.g = g;
}
}
2.3.2 解析实际节点
创建实际解析的业务类,如下:
public class ParseJbpmXml{
private Document document;
public ParseJbpmXml(String xmlPath) {
this.document = XMLDomParseUtil.getDocument(xmlPath);
}
public List<Task> parseTaskNodes(){
List<Task> taskList = new ArrayList<Task>();
List<Object> os = new XMLDomParseUtil() { // 匿名内部类嵌套
@Override
public Object dealElement(Element element, int index) {
return new Task(element.getAttribute("candidate_groups"),
element.getAttribute("g"),
element.getAttribute("name"),
parseTransitionNodes(element));
}
}.dealElementInTag(document, "task");
if(os != null){
for(Object o:os){
if(o instanceof Task){
taskList.add((Task)o);
}
}
}
return taskList;
}
/**
* 解析transition节点
*/
private List<Transition> parseTransitionNodes(Element element){
List<Transition> trans = new ArrayList<Transition>();
List<Object> os = new XMLDomParseUtil() {
@Override
public Object dealElement(Element element, int index) {
return new Transition(element.getAttribute("name"),
element.getAttribute("to"),
element.getAttribute("g"));
}
}.dealElementInTag(element, "transition");
if(os != null){
for(Object o:os){
if(o instanceof Transition){
trans.add((Transition)o);
}
}
}
return trans;
}
}
2.4 测试
public static void main(String[] args) {
ParseJbpmXml parse = new ParseJbpmXml("D:\\eclipse_powflow\\workspace\\Test\\src\\xml\\test.xml");
List<Task> taskList = parse.parseTaskNodes();
if(taskList != null){
for(int i = 0;i<taskList.size();i++){
System.out.println("-- task "+(i+1)+": --");
taskList.get(i).printLog();
}
}
}
结果输出如下: