解析xml文档总结二

上一篇文章中写了DOM和SAX的一些用法。总体上,感觉DOM解析xml文档还是比较麻烦的,因为DOM是独立于编程语言的。相对应的,JDOM则是专门用于java的接口。需要知道的是,JDOM本身不提供解析器。其他的不说了,让代码说话吧。

原始的xml文档内容如下:

<?xml version="1.0" encoding="utf-8"?>
<books>
	<book name="java">
		<author>Bruce</author>
		<price>100</price>
	</book>
	<book name="c++">
		<author>Dinail</author>
		<price>80</price>
	</book>
</books>

使用JDOM提供的类解析该文档:
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class SimpleTest {
	
	/*
	 * 读xml文档
	 * */
	public void test() throws JDOMException,IOException{
		SAXBuilder sb = new SAXBuilder();
		Document doc = sb.build("books.xml");
		Element root = doc.getRootElement();
		List<Element> list = (List<Element>)root.getChildren();//获取所有的book元素
		int length = list.size();
		for(int i = 0;i < length;i++){
			Element e = list.get(i);
			String name = e.getAttributeValue("name");
			System.out.println("book:"+name);
			List<Element> l = (List<Element>)e.getChildren();//获取book元素下的子元素
			for(int j = 0;j < l.size();j++){
				Element bookinfo = l.get(j);				
				System.out.println("  "+bookinfo.getName()+":"+bookinfo.getText());
			}
		}
	}

	/*
	 * 新建一个xml文档
	 * */
	public void build() throws JDOMException,IOException{
		Document doc = new Document();
		
		Element root = new Element("students");
		Element eleStu1 = new Element("student");
		eleStu1.setAttribute("sex","man");
		Element eleName1 = new Element("name");
		eleName1.setText("张三");
		Element eleStu2 = new Element("student");
		eleStu1.setAttribute("sex","female");
		Element eleName2 = new Element("name");
		eleName2.setText("李四");
		Element eleAge1 = new Element("age");
		eleAge1.setText("20");
		Element eleAge2 = new Element("age");
		eleAge2.setText("30");
		
		eleStu1.addContent(eleAge1);
		eleStu1.addContent(eleName1);
		eleStu2.addContent(eleAge2);
		eleStu2.addContent(eleName2);	
		root.addContent(eleStu1);
		root.addContent(eleStu2);
		doc.setRootElement(root);
		
		XMLOutputter out = new XMLOutputter();//新建一个文件输出流,JDOM提供了多种输出流
		Format format = Format.getPrettyFormat();
		format.setEncoding("gbk");
		format.setIndent("  ");//设置缩进
		out.setFormat(format);
		out.output(doc,new FileWriter("students.xml"));//写到students.xml文档中
	}
	
	public static void main(String[] args) {
		// Todo Auto-generated method stub
		try {
			new Simpletest().test();
			new Simpletest().build();
		} catch (JDOMException | IOException e) {
			// Todo Auto-generated catch block
			e.printstacktrace();
		}
	}

}

以下是读books.xml的输出
book:java
  author:Bruce
  price:100
book:c++
  author:Dinail
  price:80


代码可以看出,JDOM提供了方便的写xml的类。以下是新建的students.xml:

<?xml version="1.0" encoding="gbk"?>
<students>
  <student sex="female">
    <age>20</age>
    <name>张三</name>
  </student>
  <student>
    <age>30</age>
    <name>李四</name>
  </student>
</students>

使用JDOM来解析xml还是比较方便的吧。

另外,还有一种应用非常广泛的软件:dom4j,它和JDOM大致相似吧。下面是来自邵文一个例子:

xml文档:

<?xml version="1.0" encoding="utf-8"?>

<class> 
  <stu home="菏泽" address="北京" num="sp001" boss="sp002"> 
    <name otherName="ok">杨过</name>  
    <sex>男</sex>  
    <age>29</age> 
  </stu>  
  <stu>
    <name otherName="情人2">小三2</name>
    <sex>女</sex>
    <age>23</age>
  </stu>
  <stu num="sp002" boss="sp001"> 
    <name otherName="ok">李莫愁</name>  
    <sex>女</sex>  
    <age>47</age> 
  </stu>  
  <stu> 
    <name otherName="ok">小三</name>  
    <sex>女</sex>  
    <age>32</age> 
  </stu> 
</class>

使用dom4j操作的代码
public class SimpleTest {	

	//dom4j对xml文件进行crud操作
	public static void main(String[] args) throws Exception {
		// Todo Auto-generated method stub
		//1.得到解析器
		SAXReader saxReader = new SAXReader();
		//2.指定解析哪个xml文件
		Document document = saxReader.read(new File("src/com/dom4j/test/classes3.xml"));
		//3.遍历xml
		//list(document.getRootElement());
		//4.得到指定的内容
		//read(document);
		//5.添加一个stu到xml文件
		//add(document);
		//6.删除一个元素
		//del2(document);
		//7.更新一个元素
		//update(document);
		//8.在指定的位置添加一个新的元素
		add2(document);
	}

	//更新元素 (把学生的年龄加3)
	public static void update(Document document) throws Exception{
		
		//得到所有学生的年龄
		List<Element> stus = document.getRootElement().elements("stu");
		//用增强for循环 进行遍历
		for(Element el:stus){
			//从el中取出年龄
			Element age = el.element("age");
			int newAge = Integer.parseInt(age.getText())+3;
			age.setText(newAge+"");
			//更新属性 otherName
			Element name = el.element("name");
			name.addAttribute("otherName","ok");
		}
		//更新xml
		//直接输出会出现中文乱码
		OutputFormat output = OutputFormat.createPrettyPrint();
		output.setEncoding("utf-8");//输出的编码是utf-8
		
		XMLWriter writer = new XMLWriter(
				new FileOutputStream(new File("src/com/dom4j/test/classes3.xml")),output	
		);
		writer.write(document);
		writer.close();
	}
	
	//删除一个xml 元素中的属性
	public static void del2(Document document) throws Exception{
		//首先找到要删除的元素 2表示第三个元素
		Element stu1_name = ((Element) document.getRootElement().elements().get(2)).element("name");
		//删除 从其父节点将其删除
		stu1_name.remove(stu1_name.attribute("otherName"));
		//更新xml 经常使用 将其封装起来
		//直接输出会出现中文乱码
		OutputFormat output = OutputFormat.createPrettyPrint();
		output.setEncoding("utf-8");//输出的编码是utf-8
		
		XMLWriter writer = new XMLWriter(
				new FileOutputStream(new File("src/com/dom4j/test/classes3.xml")),output	
		);
		writer.write(document);
		writer.close();
	}
	
	//删除一个xml 元素
	public static void del(Document document) throws Exception{
		//首先找到要删除的元素 2表示第三个元素
		Element stu1 = (Element) document.getRootElement().elements().get(2);
		//删除 从其父节点将其删除
		stu1.getParent().remove(stu1);
		//更新xml 经常使用 将其封装起来
		//直接输出会出现中文乱码
		OutputFormat output = OutputFormat.createPrettyPrint();
		output.setEncoding("utf-8");//输出的编码是utf-8
		
		XMLWriter writer = new XMLWriter(
				new FileOutputStream(new File("src/com/dom4j/test/classes3.xml")),output	
		);
		writer.write(document);
		writer.close();
	}
	
	//在指定的位置添加一个学生
	public static void add2(Document document) throws Exception{
		//首先创建一个学生节点元素
		Element newStu = DocumentHelper.createElement("stu");
		Element newStu_name = DocumentHelper.createElement("name");
		newStu_name.setText("小三2");
		//给元素添加一个属性值
		newStu_name.addAttribute("otherName","情人2");
		Element newStu_sex = DocumentHelper.createElement("sex");
		newStu_sex.setText("女");
		Element newStu_age = DocumentHelper.createElement("age");
		newStu_age.setText("23");
		
		//把三个子元素(节点)加到newStu下
		newStu.add(newStu_name);
		newStu.add(newStu_sex);
		newStu.add(newStu_age);
		
		//得到所有的学生list
		List allStu = document.getRootElement().elements("stu");
		//插入到指定位置
		for(int i=0;i<allStu.size();i++){
			//取出每个人的名字
			Element name = ((Element)allStu.get(i)).element("name");
			if(name.getText().equals("杨过")){
				//满足条件之后 添加。即在杨过的后面添加一个新的元素
				allStu.add(i+1,newStu);//在i+1的位置加一个新元素
				break;
			}
		}
		//直接输出会出现中文乱码
		OutputFormat output = OutputFormat.createPrettyPrint();
		output.setEncoding("utf-8");//输出的编码是utf-8
		
		XMLWriter writer = new XMLWriter(
				new FileOutputStream(new File("src/com/dom4j/test/classes3.xml")),output	
		);
		writer.write(document);
		writer.close();
	}
	
	//添加一个元素到xml文件
	public static void add(Document document) throws Exception{
		//首先创建一个学生节点元素
		Element newStu = DocumentHelper.createElement("stu");
		Element newStu_name = DocumentHelper.createElement("name");
		newStu_name.setText("小三");
		//给元素添加一个属性值
		newStu_name.setAttributeValue("otherName","情人");//带一个线表示不建议使用 这里可以使用addAttribute
		Element newStu_sex = DocumentHelper.createElement("sex");
		newStu_sex.setText("女");
		Element newStu_age = DocumentHelper.createElement("age");
		newStu_age.setText("23");
		
		//把三个子元素(节点)加到newStu下
		newStu.add(newStu_name);
		newStu.add(newStu_sex);
		newStu.add(newStu_age);
		//把newStu加载到根元素
		document.getRootElement().add(newStu);
		
		//以上只是把内容加载到了内存,xml 文件是没有发生变化的。
		//更新xml文件,这样会出现乱码
		/*XMLWriter writer = new XMLWriter(
			new FileWriter("src/com/dom4j/test/classes3.xml")	
		);
		writer.write(document);
		writer.close();*/
		
		//直接输出会出现中文乱码
		OutputFormat output = OutputFormat.createPrettyPrint();
		output.setEncoding("utf-8");//输出的编码是utf-8
		
		XMLWriter writer = new XMLWriter(
				new FileOutputStream(new File("src/com/dom4j/test/classes3.xml")),output	
		);
		writer.write(document);
		writer.close();
		
	}

	//遍历xml文件
	public static void list(Element element){
		
		System.out.println(element.getName()+element.getTextTrim());
		
		Iterator iterator = element.elementIterator();
		
		while(iterator.hasNext()){
			
			Element e = (Element) iterator.next();
			//递归
			list(e);
		}
	}
	//指定读取某个元素(取第一个学生的信息)
	public static void read(Document document){
		//得到根元素
		Element root = document.getRootElement();
		Element stu = (Element) root.elements("stu").get(0);
		Element stu_name = stu.element("name");
		System.out.println(stu_name.getText()+" 别名" +stu_name.attributeValue("otherName"));
		//System.out.println(stu.element("name").getText());//得到指定内容的一种方式
		//System.out.println(((Element)stu.elements("name").get(0)).getText());//得到指定内容的另一种方式
		//使用xpath 实现跨层读取
		Element stu2 = (Element) document.selectNodes("/class/stu[1]");
	}
}


如果xml文档本身较为复杂,在使用代码处理xml时,可能还要涉及名字空间等一些处理,也不说了,不常用吧。关于xml,就说到这里吧。

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念