首页 > 代码库 > 利用Digester框架解析Xml

利用Digester框架解析Xml

一:首先Digester要应用的Jar包如下:

commons-beanutils-1.7.0.jar

commons-digester3-3.2.jar

commons-logging-1.2.jar

可以自行下载


二:本文要解析的Xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<remote>
	<protocol>xxx</protocol>
    <display>0x8</display>

	<default count="72">0xA5 0x81 0x07 0x18 0x00 0x00 0x20 0x00 0x65</default>
	
	<segment name="power" start="8" count="4" codes="2" default="2" >
   	    <code name="on" status="0x40A2">0x01</code>
   	    <code name="off">0x00</code>
	</segment>
	<segment name="power-temp" start="12" count="4" codes="1" default="1" >
   	    <code>0x09</code>
	</segment>
	<segment name="power-mode" start="52" count="4" codes="1" default="1" >
   	    <code>0x02</code>
	</segment>
	<segment name="power-speed" start="44" count="4" codes="1" default="1" >
   	    <code>0x04</code>
	</segment>
				
	<segment name="temperature" start="12" count="4" codes="15" default="10" >
   	    <code name="16">0x00</code>
   	    <code name="17">0x01</code>
   	    <code name="18">0x02</code>
   	    <code name="19">0x03</code>
   	    <code name="20">0x04</code>
   	    <code name="21">0x05</code>
   	    <code name="22">0x06</code>
   	    <code name="23">0x07</code>
   	    <code name="24">0x08</code>
   	    <code name="25">0x09</code>
   	    <code name="26">0x0A</code>
   	    <code name="27">0x0B</code>
   	    <code name="28">0x0C</code>
   	    <code name="29">0x0D</code>
   	    <code name="30">0x0E</code>
	</segment>
	
	<segment name="temperature-1" start="8" count="4" codes="1" default="1" >
   	    <code>0x06</code>
	</segment>
	
	<segment name="temperature-2" start="8" count="4" codes="1" default="1" >
   	    <code>0x07</code>
	</segment>
	
	<segment name="mode" start="52" count="4" codes="5" default="2" >
   	    <code name="auto" status="0x40A0">0x00</code>
   	    <code name="cold" status="0x40A0">0x02</code>
   	    <code name="dry" status="0x40A0">0x04</code>
   	    <code name="fan" status="0x40A0">0x08</code>
   	    <code name="warm" status="0x40D0">0x06</code>
	</segment>
	
	<segment name="mode-1" start="8" count="8" codes="5" default="2" >
   	    <code>0x92</code>
   	    <code>0x92</code>
   	    <code>0x92</code>
   	    <code>0x92</code>
   	    <code>0xC2</code>
	</segment>

	<segment name="mode-2" start="52" count="4" codes="5" default="2" >
   	    <code>0x0</code>
   	    <code>0x2</code>
   	    <code>0x4</code>
   	    <code>0x8</code>
   	    <code>0x6</code>
	</segment>

	<segment name="mode-3" start="20" count="4" codes="1" default="1" >
   	    <code>0x0</code>
	</segment>	
	
	<segment name="mode-4" start="44" count="4" codes="1" default="1" >
		<code>0x0C</code>
	</segment>	
		
	<segment name="speed" start="44" count="4" codes="4" default="4" >
		<code name="auto">0x00</code>
   	    <code name="high">0x0C</code>
   	    <code name="middle">0x08</code>
   	    <code name="low">0x04</code>
	</segment>
	
	<segment name="speed-1" start="8" count="8" codes="1" default="1" >
   	    <code>0x03</code>
	</segment>
	
	<segment name="swing" start="20" count="4" codes="1" default="1" >
   	    <code name="auto">0x00</code>
	</segment>
	
	<segment name="swing-1" start="8" count="4" codes="1" default="1" >
   	    <code>0x04</code>
	</segment>
	
	<segment name="swing-position" start="20" count="4" codes="1" default="1" >
   	    <code name="position">0x01</code>
	</segment>
	
	<segment name="swing-position-1" start="8" count="4" codes="1" default="1" >
   	    <code>0x05</code>
	</segment>

    <key name= "POWER" value=http://www.mamicode.com/"0x0100" segments="4">>
解析上面的Xml发现有如下几个类:


<remote> 标签对应:类Remote;
<remote> 标签的子标签<segment>对应的类:Segment ;
<segment> 标签的子标签<code>对应的类SegmentCode;
<remote> 标签的子标签<key>对应的类:Key;
<key>的子标签<segment>对应的KeySegment;
<remote> 标签的子标签<check>对应的类:Check;
<check>标签的子标签<item>对应的类:CheckItem;


下面是这些类的源码:

Remote.java:

package com.xml.remote;

import java.util.ArrayList;
import java.util.List;

public class Remote {

	private String remoteName;
	private String protocolName;
	private String defaultCode;
	
	private List<Segment> segments = new ArrayList<>();
	
	private List<Key> keys = new ArrayList<>();
	
	private List<Check> checks = new ArrayList<>();

	public void addSegments(Segment e){
		segments.add(e);
	}
	
	public List<Segment> getSegments(){
		return segments;
	}
	
	public Remote setRemoteName(String remoteName){
		this.remoteName = remoteName;
		return this;
	}

	public String getProtocolName() {
		return protocolName;
	}

	public void setProtocolName(String protocolName) {
		this.protocolName = protocolName;
	}

	public String getDefaultCode() {
		return defaultCode;
	}

	public void setDefaultCode(String defaultCode) {
		this.defaultCode = defaultCode;
	}

	public String getRemoteName() {
		return remoteName;
	}

	public List<Key> getKeys() {
		return keys;
	}

	public void addKeys(Key key) {
		this.keys.add(key);
	}

	public List<Check> getChecks() {
		return checks;
	}

	public void addChecks(Check check) {
		this.checks.add(check);
	}

	@Override
	public String toString() {
		return "Remote [remoteName=" + remoteName + ", protocolName="
				+ protocolName + ", defaultCode=" + defaultCode + ", segments="
				+ segments + ", keys=" + keys + ", checks=" + checks + "]";
	}

	
}

Segment.java

package com.xml.remote;

import java.util.ArrayList;
import java.util.List;

public class Segment {

	private String name;
	
	private int start;
	
	private int count;
	
	private int codes;
	
	private int defaultCount;
	
	private List<SegmentCode> segmentcodes = new ArrayList<>();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getStart() {
		return start;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public int getCodes() {
		return codes;
	}

	public void setCodes(int codes) {
		this.codes = codes;
	}

	public int getDefaultCount() {
		return defaultCount;
	}

	public void setDefaultCount(int defaultCount) {
		this.defaultCount = defaultCount;
	}

	public List<SegmentCode> getSegmentcodes() {
		return segmentcodes;
	}

	public void addSegmentcodes(SegmentCode segmentcode) {
		this.segmentcodes.add(segmentcode);
	}

	@Override
	public String toString() {
		return "Segment [name=" + name + ", start=" + start + ", count="
				+ count + ", codes=" + codes + ", defaultCount=" + defaultCount
				+ ", segmentcodes=" + segmentcodes + "]";
	}
	
	
	
}

SegmentCode.java:

package com.xml.remote;

public class SegmentCode {

	private String code;
	
	private String name;
	
	private String status;

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public String toString() {
		return "SegmentCode [code=" + code + ", name=" + name + ", status="
				+ status + "]";
	}
	
}

Key.java:

package com.xml.remote;

import java.util.ArrayList;
import java.util.List;

public class Key {
	
	private String name;
	
	private String value;
	
	private int segments;

	private List<KeySegment> keySegments = new ArrayList<>();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = http://www.mamicode.com/value;>
KeySegment.java

package com.xml.remote;

public class KeySegment {

	private String name;
	
	private String direction;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDirection() {
		return direction;
	}

	public void setDirection(String direction) {
		this.direction = direction;
	}

	@Override
	public String toString() {
		return "KeySegment [name=" + name + ", direction=" + direction + "]";
	}
	
}
Check.java
package com.xml.remote;

import java.util.ArrayList;
import java.util.List;

public class Check {

	private String arithmetic;
	
	private int itmes;
	
	private int start;
	
	private int count;
	
	private List<CheckItem> checkItems = new ArrayList<>();

	public String getArithmetic() {
		return arithmetic;
	}

	public void setArithmetic(String arithmetic) {
		this.arithmetic = arithmetic;
	}

	public int getItmes() {
		return itmes;
	}

	public void setItmes(int itmes) {
		this.itmes = itmes;
	}

	public int getStart() {
		return start;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public List<CheckItem> getCheckItems() {
		return checkItems;
	}

	public void addCheckItems(CheckItem checkItem) {
		this.checkItems.add(checkItem);
	}

	@Override
	public String toString() {
		return "Check [arithmetic=" + arithmetic + ", itmes=" + itmes
				+ ", start=" + start + ", count=" + count + ", checkItems="
				+ checkItems + "]";
	}

	
}
CheckItem.java:

package com.xml.remote;

public class CheckItem {

	private String flag;
	
	private int value;

	public String getFlag() {
		return flag;
	}

	public void setFlag(String flag) {
		this.flag = flag;
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = http://www.mamicode.com/value;>
好了,下面是自己写的一个XMl解析工具类:

package com.xml.remote;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.digester3.Digester;
import org.xml.sax.SAXException;

import com.xml.remote.Remote;

public class RemoteUtils {

	String remotePath;

	public RemoteUtils(String remotePath) {
		this.remotePath = remotePath;
	}

	public Remote getRemote() {

		Digester digester = new Digester();
		// 不进行XML与相应的DTD的合法性验证
		digester.setValidating(false);

		// 当遇到<remote>时创建一个com.remote.Remote对象,并将其放在栈顶
		digester.addObjectCreate("remote", Remote.class);

		// 设置<remote>元素的子元素属性
		digester.addBeanPropertySetter("remote/protocol", "protocolName");
		digester.addBeanPropertySetter("remote/default", "defaultCode");

		// 当遇到<remote>的子元素<segment>时创建一个com.remote.segment对象,并将其放在栈顶。
		digester.addObjectCreate("remote/segment", Segment.class);
		// /根据<segment>元素的属性(attribute),对刚创建的Segment对象的属性(property)进行设置
		digester.addSetProperties("remote/segment");

		// 当遇到<segment>的子元素<code>时创建一个com.remote.SegmentCode对象,并将其放在栈顶。
		digester.addObjectCreate("remote/segment/code", SegmentCode.class);
		// /根据<code>元素的属性(attribute),对刚创建的SegmentCode对象的属性(property)进行设置
		digester.addSetProperties("remote/segment/code");
		digester.addBeanPropertySetter("remote/segment/code", "code");

		digester.addObjectCreate("remote/key", Key.class);
		digester.addSetProperties("remote/key");
		
		digester.addObjectCreate("remote/key/segment", KeySegment.class);
		digester.addSetProperties("remote/key/segment");
		
		digester.addSetNext("remote/key/segment", "addKeySegment");
		digester.addSetNext("remote/key", "addKeys");
		
		///////////////
		
		digester.addObjectCreate("remote/check", Check.class);
		digester.addSetProperties("remote/check");
		
		digester.addObjectCreate("remote/check/item", CheckItem.class);
		digester.addSetProperties("remote/check/item");
		digester.addBeanPropertySetter("remote/check/item", "value");
		

		digester.addSetNext("remote/check/item", "addCheckItems");
		digester.addSetNext("remote/check", "addChecks");
		
		/////////
		
		
		
		// 当再次遇到<remote>的子元素<segment>时创建一个com.remote.Segment对象,并将其放在栈顶,同时调用第二栈顶元素(Remote对象)的addSegments方法。
		digester.addSetNext("remote/segment/code", "addSegmentcodes");
		// 当再次遇到<remote>的子元素<segment>时创建一个com.remote.Segment对象,并将其放在栈顶,同时调用第三栈顶元素(Remote对象)的addSegments方法。
		digester.addSetNext("remote/segment", "addSegments");

		InputStream is;
		try {
			is = new FileInputStream(new File(remotePath));
			return ((Remote) digester.parse(is)).setRemoteName(remotePath
					.substring(remotePath.lastIndexOf("\\") + 1));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
		return null;
	}

}

网上解析Xml的框架挺多的,本人认为这是一个不错的Xml解析框架,有点是速度快,消耗内存少,因为是基于Sax解析的,不是Dom的解析方式,学习的时候也比较简单.


下面是测试类:

package com.text;

import com.xml.remote.Check;
import com.xml.remote.CheckItem;
import com.xml.remote.Key;
import com.xml.remote.KeySegment;
import com.xml.remote.Remote;
import com.xml.remote.RemoteUtils;
import com.xml.remote.Segment;
import com.xml.remote.SegmentCode;

public class RemoteText {

	public static void main(String[] args) {
		String remotePath="C:\\text.xml"; //这里输入Xml的路径
		RemoteUtils ru = new RemoteUtils(remotePath);
		Remote remote = ru.getRemote();
		
		System.out.println("protocol="+remote.getProtocolName()+",defalut="+remote.getDefaultCode());
		System.out.println("下面输出Segments集合:");
		for(Segment s : remote.getSegments()){
			System.out.println("name="+s.getName()+",start="+s.getStart()+",count="+s.getCount()+",codes="+s.getCodes()+",defalut="+s.getDefaultCount());
			for(SegmentCode sc : s.getSegmentcodes())
				System.out.println("\t"+sc);
		}
		System.out.println("\n下面输出Keys集合:");
		for(Key k : remote.getKeys()){
			System.out.println("name="+k.getName()+",value=http://www.mamicode.com/"+k.getValue()+",segemnts="+k.getSegments());>

结果如下图: