一:首先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="0x0100" segments="4">
<segment name="power" direction="loop"/>
<segment name="power-temp" direction="none"/>
<segment name="power-mode" direction="none"/>
<segment name="power-speed" direction="none"/>
</key>
<key name= "TEMP+" value="0x0102" segments="2">
<segment name="temperature" direction="down"/>
<segment name="temperature-1" direction="none"/>
</key>
<key name= "TEMP-" value="0x0103" segments="2">
<segment name="temperature" direction="up"/>
<segment name="temperature-2" direction="none"/>
</key>
<key name= "MODE" value="0x0101" segments="5">
<segment name="mode" direction="loop"/>
<segment name="mode-1" direction="loop"/>
<segment name="mode-2" direction="loop"/>
<segment name="mode-3" direction="none"/>
<segment name="mode-4" direction="none"/>
</key>
<key name= "SPEED" value="0x0104" segments="2">
<segment name="speed" direction="loop"/>
<segment name="speed-1" direction="none"/>
</key>
<key name= "SWING" value="0x0105" segments="2">
<segment name="swing" direction="none"/>
<segment name="swing-1" direction="none"/>
</key>
<key name= "POSITION" value="0x0106" segments="2">
<segment name="swing-position" direction="none"/>
<segment name="swing-position-1" direction="none"/>
</key>
<check arithmetic="add" items="9" start="64" count="8">
<item flag="A">1</item>
<item flag="A">2</item>
<item flag="A">3</item>
<item flag="A">4</item>
<item flag="A">5</item>
<item flag="A">6</item>
<item flag="A">7</item>
<item flag="A">8</item>
<item flag="C">0</item>
</check>
</remote>
解析上面的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 = value;
}
public int getSegments() {
return segments;
}
public void setSegments(int segments) {
this.segments = segments;
}
public List<KeySegment> getList() {
return keySegments;
}
public void addKeySegment(KeySegment keySegment) {
this.keySegments.add(keySegment);
}
@Override
public String toString() {
return "Key [name=" + name + ", value=" + value + ", segments="
+ segments + ", keySegments=" + keySegments + "]";
}
}
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 = value;
}
@Override
public String toString() {
return "CheckItem [flag=" + flag + ", value=" + 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="+k.getValue()+",segemnts="+k.getSegments());
for(KeySegment ks : k.getList())
System.out.println("\t"+ks);
}
System.out.println("\n下面输出checks集合:");
for(Check c : remote.getChecks()){
System.out.println("arithmetic="+c.getArithmetic()+",items="+c.getItmes()+",start="+c.getStart()+",count="+c.getCount());
for(CheckItem ci : c.getCheckItems())
System.out.println("\t"+ci);
}
}
}
结果如下图: