Java - XML文件解析

一、前言

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包,用的时候导包就行。
1

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 解析实际节点

  创建实际解析的业务类,如下:
3

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

结果输出如下:
2

源码链接:源码-使用java编写以DOM方式解析某目录下的特定XML文件.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值