XML解析
一、XML解析
- XML解析方式分为两种:dom和sax
dom:(Document Object Model,即文档对象模型)
,处理XML的一种方式sax:(Simple API for XML)
不是官方标准,但它是XML社区事实上的标准几乎所有的XML解析器都支持它。
- XML解析开发包
- Jaxp、Jdom、dom4j
1、DOM解析
DOM模型
DOM解析器在解析XMl文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
优点:把Xml文件在内存中构造树形结构,可以遍历和修改节点
缺点:如果文件比较大,内存有压力,解析的实际时间比较长
DOM编程步骤
-
调用
DocumentBuilderFactory.newInstance()方法
得到创建DOM解析器的工厂。 -
调用
工厂对象的newDocumentBuilder方法
得到DOM解析器对象。 -
调用
DOM解析器对象的parse()方法
解析XML文档,得到代表整个文档的Document对象,就可以利用DOM特性对整个XMl文档进行操作了。
代码:
MyXml.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee id="0">
<name>Alexia</name>
<age>23</age>
<sex>Female</sex>
<weight>150</weight>
<weight><a>160</a></weight>
</employee>
<employee id="1">
<name height="178">Edward</name>
<age>24</age>
<sex>Male</sex>
</employee>
<employee id="2">
<name>Tom</name>
<age>20</age>
<sex>Female</sex>
</employee>
<employee id="3">
<name>Admin</name>
<age>21</age>
<sex>Male</sex>
</employee>
</employees>
DOMXml.java
import javax.xml.parsers.*;
import org.w3c.dom.*;
/*
* Dom解析XML
*
* @author USE
*/
public class DOMXml {
public static void main(String[] args) throws Exception {
//获得创建DOM解析器的工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//设置由此工厂生成的解析器,忽略注释
dbf.setIgnoringComments(true);
//忽略空格
dbf.setIgnoringElementContentWhitespace(true);
//调用工厂对象的方法获取DOM解析器对象
DocumentBuilder builder = dbf.newDocumentBuilder();
//调用DOM解析器对象解析XML文档,获取文档Document
Document doc = (Document) builder.parse("src/com/MyXml.xml");
//获得根节点
Element root = doc.getDocumentElement();
System.out.println(root.getTagName());
//根据标签名获得结点
NodeList nodeList = doc.getElementsByTagName("employee");
System.out.println("employess节点的个数:"+nodeList.getLength());
//遍历nodeList
for(int i=0;i<nodeList.getLength();i++){
Element element = (Element)nodeList.item(i);
//获得id属性值
String attribute = element.getAttribute("id");
System.out.println("id:" + attribute);
//获取第一个employee
if(i==0){
//获得元素下面的name文本
System.out.println("name文本值:" + element.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
//获得元素下面的sex文本
System.out.println("sex文本值:" + element.getElementsByTagName("sex").item(0).getFirstChild().getNodeValue());
//获得元素下面的age文本
System.out.println("age文本值:" + element.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
//获得第一个weight的文本值
System.out.println("weight文本值:" + element.getElementsByTagName("weight").item(0).getFirstChild().getNodeValue());
//获得第二个weight里a标签的文本值
System.out.println("weight的a文本值:" + element.getElementsByTagName("weight").item(1).getFirstChild().getFirstChild().getNodeValue());
}
}
}
}
2、SAX解析
SAX解析
在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构架代表整个DOM树的Doucment对象,从而再对XML文档进行操作;SAX解析允许在读取文档时,即对文档进行不理,而不必等到整个文档装载完才会对文档进行处理
优点:解析可以立即开始,速度快,没有内存压力
缺点:不能对节点做修改
SAX编程步骤
- 使用SAXParserFactory创建SAX解析工厂
SAXParerFactory spf = SAXParerFactory.newInstance();
- 通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
- 通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
- 设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
- 解析xml文件
xmlReader.parse("book.xml");
代码:
SAXXml.java
import java.io.File;
import javax.xml.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
/**
-
- @author USE
*/
public class SAXXml extends DefaultHandler{
//在解析整个文档开始时被调用
@Override
public void startDocument() throws SAXException {
System.out.println("开始文档");
}
//在解析整个文档结束时被调用
@Override
public void endDocument() throws SAXException {
System.out.println("结束文档");
}
//在解析元素开始时被调用
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("开始解析元素:" + qName);
}
public static void main(String[] args) throws Exception{
//创建一个sax解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
//创建解析器名称
SAXParser saxParser = spf.newSAXParser();
//创建File指明要解析的xml
File file = new File("src/com/MyXml.xml");
//解析XML文件
saxParser.parse(file, new SAXXml());
}
}
3、Dom4j解析xml
Dom4j解析
- Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
- Dom4j是一个非常优秀的Java XML API、具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j。
- 使用Dom4j开发,需下载dom4j相应的jar文件。
Dom4j编程-查询增加节点及属性
需要dom4j-1.6.1.jar
; jaxen-1.1-beta-8.jar
; jdom-1.0.jar
包
代码示例:
EmpList.xml
<?xml version="1.0" encoding="UTF-8"?>
<list>
<emp id="0">
<name>张三</name>
<age>34</age>
<gender>男</gender>
<salary>3000</salary>
</emp>
<emp id="1">
<name>王五</name>
<age>18</age>
<gender>女</gender>
<salary>6500</salary>
</emp>
<emp id="2">
<name>赵六</name>
<age>28</age>
<gender>男</gender>
<salary>4400</salary>
</emp>
<emp id="3">
<name>小明</name>
<age>20</age>
<gender>男</gender>
<salary>3300</salary>
</emp>
</list>
Emp.java(对象封装类)
public class Emp {
private int id;
private String name;
private int age;
private String gender;
private double salary;
/**
* 构造方法
*/
public Emp() {
super();
// TODO Auto-generated constructor stub
}
public Emp(int id, String name, int age, String gender, double salary) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.salary = salary;
}
/**
* get/set方法
* @return
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
/**
* toString方法
*/
@Override
public String toString() {
return "Emp [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + "]";
}
}
TestDomFJ.java
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
import com.entity.Emp;
public class TestDomFJ {
public static void main(String[] args) throws Exception {
//创建SAXReader解析器
SAXReader reader = new SAXReader();
//指明解析的文件,解析文件,获得document文档
Document doc = reader.read(new File("src/com/EmpList.xml"));
//获得根节点
Element root = doc.getRootElement();
//获得根节点下所有子节点
List<Element> elements = root.elements();
//创建List<Emp>保存所以员工对象
List<Emp> list = new ArrayList<Emp>();
//遍历子节点
for(Element element : elements){
//获取节点的属性
String id = element.attribute("id").getValue();
//获得节点及节点值
//element.elementText("name");
String name = element.element("name").getText();
String age = element.elementText("age");
String gender = element.elementText("gender");
String salary = element.elementText("salary");
Emp emp = new Emp(Integer.parseInt(id),name,Integer.parseInt(age),gender,Double.parseDouble(salary));
list.add(emp);
}
//输出list
System.out.println(list);
}
/**
* 创建文档,添加节点
* 添加子节点,addElement()
* 添加文本值,addText()
* 添加子节点并设置文本,addElement().addText()
* 添加属性,使用addAttribute( , )
*
* @throws Exception
*/
@Test
public void testAdd() throws Exception{
//list存放Emp对象
List<Emp> emps = new ArrayList<Emp>();
emps.add(new Emp(1,"张三",33,"男",9000.0));
emps.add(new Emp(2,"李四",25,"男",5000.0));
emps.add(new Emp(3,"王五",20,"男",4000.0));
//创建一个文档对象
Document doc = DocumentHelper.createDocument();
//创建根节点
Element root = doc.addElement("list");
for(Emp emp : emps){
//向根元素中添加名为emp的子元素
Element ele = root.addElement("emp");
//为emp元素添加id属性
ele.addAttribute("id", emp.getId()+"");
//添加子节点并设置节点中的文本值
ele.addElement("name").addText(emp.getName());
ele.addElement("age").addText(emp.getAge()+"");
ele.addElement("gender").addText(emp.getGender());
ele.addElement("salary").addText(emp.getSalary()+"");
}
//通过XMLWriter生成物理文件
//创建输出流,执行输出路径
FileOutputStream fos = new FileOutputStream("src/com/EmpList1.xml");
XMLWriter writer = new XMLWriter();
writer.setOutputStream(fos);
//将文档写出到指定路径中
writer.write(doc);
//关闭流
writer.close();
}
}
dom4j编程-删除修改节点及属性
TestDomFJ.java
/**
* 删除节点
* @throws Exception
*/
@Test
public void testRemove() throws Exception{
//使用SAXReader读取文档
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("src/com/EmpList.xml");
//获取根节点
Element root = doc.getRootElement();
Element element = (Element) root.elements().get(1);
System.out.println(element.attribute("id"));
//为节点删除属性
element.remove(element.attribute("id"));
System.out.println(element.attribute("id"));
Element name = element.element("name");
System.out.println(name.getText());
//将name节点删除
element.remove(name);
System.out.println(element.element("name").getText());
}
/**
* 修改
* @throws Exception
*/
@Test
public void testUpdate() throws Exception{
SAXReader sax = new SAXReader();
Document doc = sax.read("src/com/EmpList1.xml");
//获取跟节点
Element root = doc.getRootElement();
Element e2 = (Element)root.elements().get(1);
Attribute id = e2.attribute("id");
System.out.println(id.getValue());
//修改id属性值
id.setValue("20");
System.out.println(id.getValue());
//获取name节点
Element name = e2.element("name");
System.out.println(name.getText());
//修改name的文本值
name.setText("张全蛋");
System.out.println(name.getText());
}