XML 解析(二) JDOM, DOM4J,Digester

        延续XML解析的几种方式(一)的代码格式,我们来写一个用JDOM解析XML的方法,这个方法首先依赖于外部包org.jdom。让我们仔细看看代码,知道他解析XML的简单和效率。
public class ExecuteXMLwithJDOM implements XMLExecutor {
        //JDOM创建XML
	public void createXML(String fileName) {
		Document document;
		Element root;
		root = new Element("employees");
		document = new Document(root);
		
		Element employee1 = new Element("employee");
		root.addContent(employee1);
		Element name1 = new Element("name");
		name1.setText("tangsir");
		employee1.addContent(name1);
		Element sex1 = new Element("sex");
		sex1.setText("m");
		employee1.addContent(sex1);
		Element age1 = new Element("age");
		age1.setText("31");
		employee1.addContent(age1);
		
		Element employee2 = new Element("employee");
		root.addContent(employee2);
		Element name2 = new Element("name");
		name2.setText("tangsir");
		employee2.addContent(name2);
		Element sex2 = new Element("sex");
		sex2.setText("m");
		employee2.addContent(sex2);
		Element age2 = new Element("age");
		age2.setText("31");
		employee2.addContent(age2);
		
		XMLOutputter XMLOut = new XMLOutputter();
		try {
			XMLOut.output(document, new FileOutputStream(fileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
        //JDOM解析XML
	public void parseXML(String fileName) {
		SAXBuilder sb = new SAXBuilder();
		Document doc;
		Element root = null;
		try {
			doc = sb.build(fileName);
			// 获取XML根节点,这里的根节点是employees
			root = doc.getRootElement();
		} catch (JDOMException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
		// 获取根节点的一级子节点列表
		List list = root.getChildren("employee");
		for (int i = 0; i < list.size(); i++) {
			Element e = (Element) list.get(i);
			System.out.println(e.getChild("name") + "  =  "
					+ e.getChildText("name"));
			System.out.println(e.getChild("sex") + "  =  "
					+ e.getChildText("sex"));
			System.out.println(e.getChild("age") + "  =  "
					+ e.getChildText("age"));
		}
	}
}

         就这么简单,我们就实现了之前很多行代码的XML的解析,根据不要重复造轮子的经验,我们没必要自己再写个什么东西来解析XML,就用现成的JDOM包,两三句代码就搞定一个XML解析了。写入XML快,解析XML更快,痛快吧,童鞋们!

         为减少DOM、SAX的编码量,JDOM才出现的;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX。

         也许你要说JDOM已经很方便了,但是趁热打铁,让我们再上一段DOM4J的代码
public class ExecuteXMLwithDOM4J implements XMLExecutor {

	public void createXML(String fileName) {
		Document document = DocumentHelper.createDocument();
		Element employees = document.addElement("employees");
		//add tangsir info into document
		Element employee1 = employees.addElement("employee");
		Element name1 = employee1.addElement("name");
		name1.setText("tangsir");
		Element sex1 = employee1.addElement("sex");
		sex1.setText("m");
		Element age1 = employee1.addElement("age");
		age1.setText("31");
		//add jianqiangsir info into document
		Element employee2 = employees.addElement("employee");
		Element name2 = employee2.addElement("name");
		name2.setText("jianqiangsir");
		Element sex2 = employee2.addElement("sex");
		sex2.setText("fm");
		Element age2 = employee2.addElement("age");
		age2.setText("30");
		try {
			Writer fileWriter = new FileWriter(fileName);
			XMLWriter xmlWriter = new XMLWriter(fileWriter);
			xmlWriter.write(document);
			xmlWriter.close();
		} catch (IOException e) {

			System.out.println(e.getMessage());
		}
	}

	public void parseXML(String fileName) {
		File inputXml = new File(fileName);
		SAXReader saxReader = new SAXReader();
		try {
			Document document = saxReader.read(inputXml);
			Element employees = document.getRootElement();
			for (Iterator i = employees.elementIterator(); i.hasNext();) {
				Element employee = (Element) i.next();
				for (Iterator j = employee.elementIterator(); j.hasNext();) {
					Element node = (Element) j.next();
					System.out.println(node.getName() + ":" + node.getText());
				}
			}
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("dom4j parserXml");
	}
}

        怎样,dom4j是不是又让你眼前一亮菊花一紧? 如此方便的XML解析包。如此简单的代码,几句话将一个XML文件给解析出来。DOM4J的代码,我没有加一句注释,其实不需要注释你也应该很容易看出来每一步在做什么,真实的实现了所见即所得。

        DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

        这里,我还要给大家介绍一种方便的XML解析方法,这种方法更符合面向对象的编码原则,更容易让Java程序员所理解,就是Apache所推出的Digester的解析方式,这种方式需要依赖于commons-digester和commons-collections包。代码如下:

        首先我们定义一个Employee类,这个类中的属性就是XML中Employee标签下的字段。这个类很简单,就是个简单的javabean,有getter,setter方法和一个无参构造方法。
public class Employee {
	private String name;
	private String sex;
	private int age;
	
	public Employee() {
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

        然后定义一个Employees类,这个类中只有一个ArrayList成员变量,该成员变量中存储的就是每个Employee对象。我们在代码中也给出了添加对象和获取List中对应Employee的方法,代码如下:
public class Employees {
	private ArrayList elist;
	
	public Employees(){
		elist = new ArrayList();
	}
	public void addEmployee(Employee stu){
		elist.add(stu);
	}
	public Employee getEmployee(int i){
		return (Employee) elist.get(i);
	}
}
in
        有了这两个对象对应XML的两个主要节点,我们就可以开始写Digester解析代码了
public class ParseXMLwithDigester {
	
	public void parseXML(String fileName) {
		Digester digester = new Digester();
		digester.addObjectCreate("employees", Employees.class);
		   digester.addObjectCreate("employees/employee", Employee.class);
		      digester.addBeanPropertySetter("employees/employee/name","name");
		      digester.addBeanPropertySetter("employees/employee/sex","sex");
		      digester.addBeanPropertySetter("employees/employee/age","age");
		    digester.addSetNext("employees/employee", "addEmployee"); 
			try {
				Employees employs = (Employees) digester.parse(new File(fileName));
				Employee emp = employs.getEmployee(0);
	System.out.println(emp.getName()+ ""+ emp.getSex()+""+ emp.getAge());
				Employee emp2 = employs.getEmployee(1);
	System.out.println(emp2.getName()+ ""+ emp2.getSex()+""+ emp2.getAge());
				}catch(Exception e){
					e.printStackTrace();
				}
	}
}

        从上面的代码中可以看出,Digester是将XML标签映射成实际的javabean,然后通过他自身的几个简单方法将其封装成一定结构的树来解析的。该方法容易被面向对象开发者所理解,但是如果XML过于复杂的话,会产生很多映射对象,开销也相应的增大了。

        注意: 以上几段代码中(除了Digester)都出现过Element,Document等等字段,我们使用DOM的时候就需要引入DOM包下面的这些字段,使用JDOM的时候需要引入JDOM包下面的这些字段,使用DOM4J的时候引入的应该是DOM4J包下面的这些字段,不要引入错误,导致编译都通不过哟。

        最后,同样贴出测试代码
	public static void main(String[] args) {
		//JDOM解析XML测试
		ExecuteXMLwithJDOM jdom = new ExecuteXMLwithJDOM();
		jdom.createXML("C:\\gggg.xml");
		jdom.parseXML("C:\\gggg.xml");
		//DOM4J解析MXL测试
		ExecuteXMLwithDOM4J dom4j = new ExecuteXMLwithDOM4J();
		dom4j.createXML("C:\\xxxx.xml");
		dom4j.parseXML("C:\\xxxx.xml");
		//Digester解析XML测试
		ParseXMLwithDigester digs = new ParseXMLwithDigester();
		digs.parseXML("C:\\xxxx.xml");
	}
}

        最后附上XML解析需要用到的包,大家可以尝试一下方便的解析了!

猜你喜欢

转载自goalietang.iteye.com/blog/2030255