前言:xml解析主要分为dom解析和sax解析,dom是W3C组织推荐的处理XML文档的一种方式,sax不是官方标准,但它是xml社区事实上的标准(相当于是一个民间标准),几乎
所有的xml解析器都支持它。dom和sax都是一种模型,都需要使用具体的代码去实现它。dom4j组织根据自己的解析器推出了解析xml的api dom4j,它是一个十分优秀的API,具有
性能优异、功能强大和极易使用的特点,一经推出就风靡。
一、sax解析
1.1sax解析的特点
sax解析xml文件时,遇到开始标签、结束标签、开始解析文件,文件解析结束,字符内容和空白字符时都会触发各自的方法。
优点:适合解析大文件,对内存要求不高。轻量级的解析数据方式,效率更高
缺点:不能随机解析文件,不能修改xml文件,只能进行查询
在基于sax的程序中,有五个最常用的sax事件
startDocument() ---> 解析器发现了文档的开始标签
endDocument() ---> 解析器发现了文档结束标签
startElement() ---> 解析器发现了一个起始标签
character() ---> 解析器发现了标签里面的文本值
endElement() ---> 解析器发现了一个结束标签
利用SAX解析xml文档,涉及两个部分:解析器和时间处理器。例如:
package XMLjiexi;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.sun.org.apache.xerces.internal.xni.QName;
/*
使用sax解析去解析xml文件,sax解析的机制为遇到开始标签结束标签开始解析文件,遇到文本内容和空白内容都会触发方法,
特点:适合解析大文件,对内存要求不高,轻量级的解析,效率更高
缺点:不能随机修改,只能进行查询,不能随机进行解析,因为是从上到下的解析方式
*/
public class Saxparse {
private List<student> stus;
private student stu;
public List<student> read(String filePath) {
stus=new ArrayList<>();
try {
//第一步,获取sax解析工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
//第二步,获得sax解析器对象
SAXParser parser = factory.newSAXParser();
//第三步,利用解析器对象解析xml文件,传的第一个is对象为需要解析的xml文件的路径,第二个对象dh为
//sax解析的关键内容,这个内部类写了很多个方法,解析xml文档的方法,我们只需要去实现五个关键的方法。
parser.parse(filePath,new DefaultHandler() {
String cuurentQname;
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//System.out.println("获取元素内容");
String text=new String(ch, start, length);
if("name".equals(this.cuurentQname)) {
stu.setName(text);
}else if("age".equals(this.cuurentQname)) {
stu.setAge(Integer.parseInt(text));
}
}
@Override
public void endDocument() throws SAXException {
System.out.println("文档解析结束");
}
//当解析到下一个stu时,这个时候已经解析完一个部分了,把这个所有内容保存进list对象stus里面去。
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//System.out.println("元素解析结束");
if(qName.equals("stu")) {
stus.add(stu);
}
this.cuurentQname=null;
}
@Override
public void startDocument() throws SAXException {
System.out.println("文档开始解析");
}
/*各个参数的含义
* uri:命名空间
* localName:不带前缀名
* qName:带前缀名
* attributes:属性对象
*/
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
this.cuurentQname=qName;
//System.out.println("元素开始解析");
if(qName.equals("stu")) {
//当解析到stu时,需要创建一个对象去存储接下来会获取到的属性值
stu=new student();
//属性内容可以通过属性名或者索引来获取属性内容
String id = attributes.getValue("id");
//属性内容的格式是string类型的,需要把它转换为long内容再存进域对象stu里面。ps:开始设置
//stu时的属性为long类型
stu.setId(Long.parseLong(id));
}
}
} );
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return stus;
}
public static void main(String[] args) {
List<student> stus = new Saxparse().read("src/XMLjiexi/Student.xml");
System.out.println(stus.toString());
}
}
二、DOM解析
2.1dom解析的特点
采用dom解析,会将xml文档全部加载到内存当中,然后将xml文档中的所有内容转化为tree上的节点(对象).
优点:可以随机解析,可以修改文件,可以创建xml文件
缺点:适合解析小型文件,对内存要求较高。
三、dom4j解析
3.1dom4j解析简介
dom4j是一个简单、灵活的开放源代码的库。现在很多软件采用的dom4j,使用dom4j开发,需要下载相应的jar包。
3.2dom4j创建、解析、修改xml文件
创建一个和遍历一个xml文档
package XMLjiexi;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/*
* 使用dom4japi可以创建和解析和修改xml文件,以下是一些创建和修改相关的操作以及注释
*/
public class Dom4jTest {
//创建一个新的xml文件
public void createDom(String file){
//获得文档对象
Document document = DocumentHelper.createDocument();
//添加根元素
Element root = document.addElement("root");
//根元素下面添加子元素及其属性
Element city = root.addElement("city");
city.addAttribute("name", "上海");
//city元素下面添加子元素及其文本值
Element num = city.addElement("peopleNumber");
num.addText("23343");
Element sal = city.addElement("salary");
sal.addText("12000");
Element city1 = root.addElement("city");
city1.addAttribute("name", "北京");
//city元素下面添加子元素及其文本值
Element num1 = city1.addElement("peopleNumber");
num1.addText("11111");
Element sal1 = city1.addElement("salary");
sal1.addText("14000");
try {
// 输出格式化xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xw = new XMLWriter(new FileOutputStream(new File(file)),format);
xw.write(document);
xw.flush();
xw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void readXML(String filePath){
try {
//获得一个SAXReader对象
SAXReader reader = new SAXReader();
File file = new File(filePath);
//读取这个要解析的xml文件
Document document = reader.read(file);
//获得document中的根节点
Element rootElement = document.getRootElement();
//获得根节点下面所有的子节点
List<Element> elements = rootElement.elements();
//遍历elements集合,拿到每一个子节点
for(Element e:elements){
//获得元素的名字和文本值
String s = e.attributeValue("id");
System.out.println(e.getName()+"节点的id属性的值为:"+s);
//获得当前这个子节点下面所有的子节点
List<Element> elements2 = e.elements();
//遍历elements2集合,拿到每一个子节点
for(Element e2:elements2){
System.out.println(e2.getName()+" : "+e2.getText());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Dom4jTest t = new Dom4jTest();
String filePath = "src/XMLjiexi/app.xml";
t.createDom(filePath);
// t.readXML(filePath);
}
}
修改一个xml文件,需要下载相应的jar包
package XMLjiexi;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Dom4jUpdate {
public void modifyXML(File filePath) {
try {
SAXReader reader = new SAXReader();
Document document = reader.read(filePath);
//System.out.println("nihao");
//定位节点需要用到一个jar包:jaxen-1.1-beta-6.jar
List list = document.selectNodes("//city/@name");
//System.out.println("nihaomingtian");
Iterator iter = list.iterator();
while(iter.hasNext()) {
Attribute att = (Attribute)iter.next();
if(att.getValue().equals("上海")) {
att.setValue("成都");
}
}
XMLWriter output=new XMLWriter(new FileWriter(new File("C:/xml/app-modify.xml")));
} catch (DocumentException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
Dom4jUpdate update = new Dom4jUpdate();
update.modifyXML(new File("C:/Users/YF/eclipse-workspace-javaee/XML/src/XMLjiexi/app.xml"));
}
}
