每天多一点之DOM4J+XPATH
1、About DOM4J
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXP也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。
2、DOM4j中,获得Document对象的方式有三种:
1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File(“src/input.xml"));2.解析XML形式的文本,得到document对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);3.主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点Element root = document.addElement("members");
3、节点对象
1.获取文档的根节点.
Element root = document.getRootElement();
2.取得某个节点的子节点.
Element element=node.element(“书名");
3.取得节点的文字
String text=node.getText();
4、dom4j快速入门
1、遍历整个xml文件
public static void list(Element e){ System.out.println(e.getName()+e.getText().trim()); Iterator it=e.elementIterator(); while(it.hasNext()){ Element element=(Element) it.next();list(element);}}
2.读取xml的某个标签内容(比如,读取第一个学生的名字)
public static void read(Document doc){ Element stu=doc.getRootElement().element("名字"); Element name=stu.element("名字"); System.out.println(stu.getText());}3.添加xml标签(加入一个学生)
public static void add(Document doc) throws IOException{ //1.创建一个元素 Element e=DocumentHelper.createElement("学生");//e.setText("贾宝玉"); //在学生标签下,加入名字 Element name=DocumentHelper.createElement("名字"); name.setText("小龙女");e.add(name); //2.挂到根元素下 doc.getRootElement().add(e); //3.更新文档. OutputFormat output=OutputFormat.createPrettyPrint();output.setEncoding("utf-8"); //分析 //XMLWriter writer=new XMLWriter(new FileWriter("src/myClass.xml"),output); //一种解决乱码的方法 /*XMLWriter writer=new XMLWriter( new OutputStreamWriter(new FileOutputStream(new File("src/myClass.xml")),"utf-8"),output);*/ //第二种方法解决乱码 XMLWriter writer=new XMLWriter(new FileOutputStream(new File("src/myClass.xml")),output); writer.write(doc);writer.close(); }
5、快速入门2
1.文档中全为英文,不设置编码,直接写入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();2.文档中含有中文,设置编码格式写入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();
// 指定XML编码format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();出现乱码. new OutputStreamWriter(new FileOutputStream("src/myClass.xml"),"utf-8")
l4.取得某节点下所有名为“member”的子节点,并进行遍历.
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}l5.对某节点下的所有子节点进行遍历.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}l6.在某节点下添加子节点.
Element ageElm = newMemberElm.addElement("age");l7.设置节点文字.
element.setText("29");l8.删除某节点.
//childElm是待删除的节点,parentElm是其父节点parentElm.remove(childElm);
l9.添加一个CDATA节点.
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());l1.取得某节点下的某属性
Element root=document.getRootElement();
//属性名nameAttribute attribute=root.attribute("size");
l2.取得属性的文字
String text=attribute.getText();l 3.删除某属性
Attribute attribute=root.attribute("size");
root.remove(attribute);l3.遍历某节点的所有属性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}l4.设置某节点的属性和文字.
newMemberElm.addAttribute("name", "sitinspring");l5.设置属性的文字
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
6、Dom4j在指定位置插入节点
l1.得到插入位置的节点列表(list)
l2.调用list.add(index,elemnent),由index决定element的插入位置。
lElement元素可以通过DocumentHelper对象得到。示例代码:
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
List list = root.element("书").elements();
list.add(1, aaa);
//更新document
7、字符串与XML的转换
l1.将字符串转化为XML
String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);l2.将文档或节点的XML转化为字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();
8、什么是XPATH
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。
注:有关XPATH的更多 参考XPath Tutorial
9、案例
XML(exercise.xml):
<?xml version="1.0" encoding="UTF-8"?> <students> <student sid="001"> <name>小明</name> <course> <java>90</java> <oracle>90</oracle> <vb>89</vb> </course> </student> <student sid="002"> <name>小李</name> <course> <java>9</java> <oracle>70</oracle> <vb>8</vb> </course> </student> <student sid="003"> <name>小韩</name> <course> <java>90</java> <oracle>70</oracle> <vb>85</vb> </course> </student> <student sid="004"> <name>小明名</name> <course> <java>34</java> <oracle>50</oracle> <vb>58</vb> </course> </student> <student sid="005"> <name>小红</name> <course> <java>29</java> <oracle>39</oracle> <vb>88</vb> </course> </student> <student sid="006"> <name>小米</name> <course> <java>99</java> <oracle>99</oracle> <vb>67</vb> </course> </student> </students>
package com.exercise.dom4j; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Scanner; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4jExercise { private Scanner scanner = new Scanner(System.in); private Document doc; public static void main(String[] args) { Dom4jExercise domExercise = new Dom4jExercise(); domExercise.doc = getDocument(); domExercise.show(); } public void show() { String option = ""; do { System.out.println("查看所有学生的成绩------view"); System.out.println("按照学生学号查询学生成绩-----query"); System.out.println("添加一个学生-----add"); System.out.println("按照学号更改一个学生的信息-----change"); System.out.println("按照学号去删除一个学生------remove"); System.out.println("保存学生信息-----save"); System.out.println("退出系统--------exit"); System.out.println("请输入你要的操作:"); option = scanner.next(); if (option.equals("view")) { showAllScores(); } else if (option.equals("query")) { queryById(); } else if (option.equals("add")) { addStu(); } else if (option.equals("change")) { changeInfo(); } else if (option.equals("remove")) { removeStu(); } else if (option.equals("save")) { saveInfo(); } else if (option.equals("exit")) { System.exit(0); } } while (true); } // 根据学号 删除学生 private void removeStu() { System.out.println("请输入你要删除的学生的学号:"); String sid = scanner.next(); // 获取所有student节点 Element root = doc.getRootElement(); // 删除对应学号的学生 for (Iterator i = root.elementIterator(); i.hasNext();) { Element element = (Element) i.next(); if (element.attributeValue("sid").equals(sid)) { element.getParent().remove(element); break; } } } // 根据学号修改学生信息 private void changeInfo() { System.out.println("请输入你要修改的学生的学号:"); String sid = scanner.next(); // 获取根节点 Element root = doc.getRootElement(); Element element = null; // 遍历获取的所有student节点,获取对应学号的学生信息 for (Iterator i = root.elementIterator(); i.hasNext();) { element = (Element) i.next(); if (element.attributeValue("sid").equals(sid)) { System.out.println("学号=" + element.attributeValue("sid") + "\t\t姓名=" + getElementValue(element, "name") + "\tJava=" + getElementValue(element.element("course"), "java") + "\tOracle=" + getElementValue(element.element("course"), "oracle") + "\tVB=" + getElementValue(element.element("course"), "vb")); break; } } System.out.println("修改学号-----1"); System.out.println("修改姓名-----2"); System.out.println("修改Java成绩-----3"); System.out.println("修改Oracle成绩-----4"); System.out.println("修改VB成绩-----5"); System.out.println("请选择您要修改的信息:"); String inStr = scanner.next(); if (inStr.equals("1")) { System.out.println("请输入新学号:"); String newSid = scanner.next(); element.addAttribute("sid", newSid); } else if (inStr.equals("2")) { System.out.println("请输入新姓名:"); String newName = scanner.next(); element.element("name").setText(newName); } else if (inStr.equals("3")) { System.out.println("请输入新Java成绩:"); String newJava = scanner.next(); element.element("java").setText(newJava); } else if (inStr.equals("4")) { System.out.println("请输入新Oracle成绩:"); String newOracle = scanner.next(); element.element("oracle").setText(newOracle); } else if (inStr.equals("5")) { System.out.println("请输入新VB成绩:"); String newVB = scanner.next(); element.element("vb").setText(newVB); } System.out.println("修改后:"); System.out.println("学号=" + element.attributeValue("sid") + "\t\t姓名=" + getElementValue(element, "name") + "\tJava=" + getElementValue(element.element("course"), "java") + "\tOracle=" + getElementValue(element.element("course"), "oracle") + "\tVB=" + getElementValue(element.element("course"), "vb")); } // 添加学生 private void addStu() { System.out.println("添加一个新学生:"); System.out.println("请输入学号:"); String sid = scanner.next(); System.out.println("请输入姓名:"); String name = scanner.next(); System.out.println("请输入java成绩:"); String javaScore = scanner.next(); System.out.println("请输入oracle成绩:"); String oracleScore = scanner.next(); System.out.println("请输入VB成绩:"); String vbScore = scanner.next(); // 创建节点 Element stu = doc.addElement("student"); Element stu_name = doc.addElement("name"); Element stu_course = doc.addElement("course"); Element stu_java = doc.addElement("java"); Element stu_oracle = doc.addElement("oracle"); Element stu_vb = doc.addElement("vb"); // 设置属性、节点值 stu.addAttribute("sid", sid); stu_name.setText(name); stu_java.setText(javaScore); stu_oracle.setText(oracleScore); stu_vb.setText(vbScore); // 添加节点 stu.add(stu_name); stu.add(stu_course); stu_course.add(stu_java); stu_course.add(stu_oracle); stu_course.add(stu_vb); // 添加到根节点 doc.getRootElement().add(stu); } // 根据输入的学号查询学生成绩 private void queryById() { System.out.println("请输入学号:"); String sid = scanner.next(); // 获取所有student节点 Element root = doc.getRootElement(); // 遍历获取的所有student节点,获取对应学号的学生信息 for (Iterator i = root.elementIterator(); i.hasNext();) { Element element = (Element) i.next(); if (element.attributeValue("sid").equals(sid)) { System.out.println("学号=" + element.attributeValue("sid") + "\t\t姓名=" + getElementValue(element, "name") + "\tJava=" + getElementValue(element.element("course"), "java") + "\tOracle=" + getElementValue(element.element("course"), "oracle") + "\tVB=" + getElementValue(element.element("course"), "vb")); break; } } } // 显示所有学生的成绩 private void showAllScores() { System.out.println("显示所有学生的成绩:"); //获取所有student节点 List<Element> list = doc.selectNodes("//students/student"); // 遍历获取的所有student节点下的信息 for (Element element : list) { System.out.println("学号=" + element.attributeValue("sid") + "\t\t姓名=" + getElementValue(element, "name") + "\tJava=" + getElementValue(element.element("course"), "java") + "\tOracle=" + getElementValue(element.element("course"), "oracle") + "\tVB=" + getElementValue(element.element("course"), "vb")); } } // 获取element的信息 private String getElementValue(Element element, String tagName) { return element.element(tagName).getText(); } // 保存学生信息 private void saveInfo() { OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); // 指定XML编码 XMLWriter writer; try { writer = new XMLWriter(new FileOutputStream(new File( "src/com/exercise/dom4j/exercise.xml")), format); writer.write(doc); writer.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("保存成功!"); } // 获取document private static Document getDocument() { Document doc = null; try { // 1.得到SAXReader 解析器 SAXReader saxReader = new SAXReader(); // 2.指定去解析哪个文件 doc = saxReader.read("src/com/exercise/dom4j/exercise.xml"); } catch (Exception e) { e.printStackTrace(); } return doc; } }