一:首先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:
@H_404_77@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
@H_404_77@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:
@H_404_77@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:
@H_404_77@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 + ",keySegments=" + keySegments + "]"; } }
KeySegment.java
@H_404_77@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 @H_404_77@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 + ",count=" + count + ",checkItems=" + checkItems + "]"; } } CheckItem.java:
@H_404_77@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解析工具类:
@H_404_77@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的解析方式,学习的时候也比较简单.
下面是测试类:
@H_404_77@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); } } }
结果如下图: