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() { // 匿名内部类嵌套@Overridepublic 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() {@Overridepublic 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();}}}
结果输出如下:
源码链接:源码-使用java编写以DOM方式解析某目录下的特定XML文件.