dom4j操作xml基础--Visitor访问模式解析XML
|
|
1 # 大 中 小 发表于 2008-08-10 15:57:31
http://www.blogjava.net/bulktree/archive/2008/08/10/221122.html
dom4j遍历xml文档树有种很特别的方式就是访问者(Visitor)模式,初次接触Visitor模式,写出个人理解大家交流! Visitor访问者模式定义:作用于某个对象树中各个对象的操作. 它可以使你在不改变这些对象树本身的情况下,定义作用于这些对象树各个节点的新操作。 先看以下代码:Person为简单的vo类 package org.bulktree.visitor; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class ReadCollection { private Collection c = null; ReadCollection() { /* * 准备数据-String对象-Person对象-Integer对象-List对象 */ String str = "bulktree.laoshulin"; Person person = new Person("bulktree", "22", "M"); Integer a = new Integer(99); /* * 使用范型 */ List<String> list = new ArrayList<String>(); list.add("BULKTREE"); list.add("LAOSHULIN"); list.add("OAKERTREE"); c = new ArrayList(); c.add(str); c.add(person); c.add(a); c.add(list); } /** * 遍历Collection中的每一个对象并打印 */ public void testCollection() { Iterator iter = getCollection().iterator(); while (iter.hasNext()) { Object o = iter.next(); if (o instanceof String) { System.out.println("String--> " + o.toString()); } else if (o instanceof Person) { readPerson((Person) o); } else if (o instanceof Integer) { Integer inta = (Integer) o; System.out.println(inta.intValue()); } else if (o instanceof List) { readList((List) o); } } } public Collection getCollection() { return c; } private void readPerson(Person person) { System.out.println("person-name-> " + person.getName()); System.out.println("person-age-> " + person.getAge()); System.out.println("person-sex-> " + person.getSex()); } private void readList(List<String> list) { /* * 增强的for循环 */ for (String s : list) { System.out.println(s); } } public static void main(String[] args) { new ReadCollection().testCollection(); } } 我们使用了 instanceof来判断 Object对象 o 的类型,这样做的缺点是代码中If/else if 很繁琐,而JDK中的范型又限制了只能使用相同的类型,这时Vistor访问模式派上用场了。 当我们要访问Collection的每一个Element(被访问者)时,定义一个accept操作使其具有可被访问性,我们定义一个Visiable接口,使Collection的每一个Element继承这个接口,实现自身的访问操作 package org.bulktree.visitor; /** * 可访问性--接收一个访问者 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public interface Visitable { public void accept(Visitor visitor); } 下来是四个被访问的类型String,Integer,Person,Collection的实现类 package org.bulktree.visitor; /** * 被访问者--String对象 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class StringElement implements Visitable { private String str; public StringElement(String str) { this.str = str; } public String getStr() { return str; } public void accept(Visitor visitor) { visitor.visitString(this); } } package org.bulktree.visitor; /** * 被访问者--Integer对象 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class IntegerElement implements Visitable { private Integer i; public IntegerElement(Integer i) { this.i = i; } public Integer getI() { return i; } public void accept(Visitor visitor) { visitor.visitInteger(this); } } package org.bulktree.visitor; import java.util.Collection; /** * 被访问者--Person对象 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class PersonElement implements Visitable{ private Person p; public PersonElement(Person p) { this.p = p; } public Person getP() { return p; } public void accept(Visitor visitor) { visitor.visitPerson(this); } } package org.bulktree.visitor; import java.util.Collection; import java.util.List; /** * 被访问者--Collection对象 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class CollectionElement implements Visitable { private Collection collection; public CollectionElement(Collection collection) { this.collection = collection; } public Collection getCollection() { return collection; } public void accept(Visitor visitor) { visitor.visitCollection(collection); } } 下来定义一个访问者Visitor接口,它可以访问Integer,String,Person(VO对象),Collection类型 package org.bulktree.visitor; import java.util.Collection; /** * 访问者接口 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public interface Visitor { public void visitString(StringElement str); public void visitInteger(IntegerElement i); public void visitCollection(Collection collection); public void visitPerson(PersonElement perE); } 关键的Visitor实现类 package org.bulktree.visitor; import java.util.Collection; import java.util.Iterator; /** * 访问者实现类 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class VisitorImpl implements Visitor { /* *访问字符串,仅对字符串输出 */ public void visitString(StringElement str) { System.out.println("*******************字符串输出*************************"); System.out.println(str.getStr()); } /** * 访问Integer类型 */ public void visitInteger(IntegerElement i) { System.out.println("*******************整型输出*************************"); System.out.println(i.getI()); } /** * 访问Collection对象,遍历每一个元素 * 使用了一个if语句判断属于Visitable哪一个被访问对象,然后调用相应的accept方法 * 实现递归调用 */ public void visitCollection(Collection collection) { Iterator iter = collection.iterator(); while (iter.hasNext()) { Object o = iter.next(); if (o instanceof Visitable) { ((Visitable) o).accept(this); } } } /** * 访问单个Person对象 */ public void visitPerson(PersonElement perE) { System.out.println("*******************Person对象输出*************************"); Person person = perE.getP(); System.out.println("person-name-> " + person.getName()); System.out.println("person-age-> " + person.getAge()); System.out.println("person-sex-> " + person.getSex()); } } 客户端测试: package org.bulktree.visitor; import java.util.ArrayList; import java.util.Collection; /** * Visitor模式客户端 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class VisitorMain { public static void main(String[] args) { Visitor visitor = new VisitorImpl(); /* * 访问字符串 */ System.out.println("======================访问字符串========================="); StringElement stringE = new StringElement( "bulktree.laoshulin.oakertree"); visitor.visitString(stringE); /* * 访问集合 */ System.out.println("=======================访问集合========================"); Collection list = new ArrayList(); StringElement str1 = new StringElement("aaa"); StringElement str2 = new StringElement("bbb"); list.add(str1); list.add(str2); PersonElement perE1 = new PersonElement(new Person("LAOSHULIN", "22", "M")); PersonElement perE2 = new PersonElement(new Person("BULKTREE", "21", "W")); list.add(perE1); list.add(perE2); IntegerElement intE1 = new IntegerElement(new Integer(99)); IntegerElement intE2 = new IntegerElement(new Integer(100)); list.add(intE1); list.add(intE2); visitor.visitCollection(list); /* * 访问Person */ System.out.println("======================访问Person========================="); Person p = new Person("BULKTREE", "22", "M"); PersonElement perE = new PersonElement(p); visitor.visitPerson(perE); /* * 访问Integer */ System.out.println("=====================访问Integer=========================="); IntegerElement intE = new IntegerElement(new Integer(77)); visitor.visitInteger(intE); } } 使用访问者模式的前提是对象群结构中(Collection) 中的对象类型很少改变,在两个接口Visitor(访问)和Visitable(可访问)中,确保Visitable很少变化,也就是说,确保不能有新的元素类型加进来,可以变化的是访问者行为或操作,也就是Visitor的不同子类可以有多种,这样使用访问者模式最方便,当系统中存在着固定的数据结构,且有着不同的行为,访问者模式也许是个不错的选择 package org.bulktree.xml; import java.io.File; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.VisitorSupport; import org.dom4j.io.SAXReader; /** * dom4j访问者模式解析xml文档 * @author bulktree Email: laoshulin@gmail.com * @date Aug 10, 2008 */ public class ReadXmlVisitor { ReadXmlVisitor() { File file = new File("student.xml"); SAXReader saxReader = new SAXReader(); try { Document doc = saxReader.read(file); doc.accept(new MyVisitor()); } catch (DocumentException e) { e.printStackTrace(); } } public static void main(String[] args) { new ReadXmlVisitor(); } } /* * org.dom4j 包里有Visitor接口,VisitorSupport是它的实现类,定义了多个重载的visit方法 */ class MyVisitor extends VisitorSupport { public void visit(Attribute attr) { String name = attr.getName(); String value = attr.getValue(); System.out.println("Attribute--> " + name + " : " + value); } public void visit(Element element) { String name = element.getName(); if (element.isTextOnly()) { System.out .println("Element--> " + name + " : " + element.getText()); } else { System.out.println("Element-->" + name); } } }
快乐渡过每一天,减肥坚持每一天
|
|||||
|


