下面是简单的总结三种常用的java对xml文件的操作
1. dom方式对xml进行操作,这种操作原理是将整个xml文档读入内存总,在内存中进行操作,当xml文档非常庞大的时候就会出现内存溢出的异常,这种方式可以进行增删改查的操作。
2. sax方式进行xml的操作,这种方式则不是将整个xml文档读入到内存中进行操作,sax的操作方式是实时将文档中的数据进行处理,这种方式是一个标签一个标签的进行读取,然后由程序员去实现一个自定义的操作,那么这里需要去实现ContentHandler这个接口中的方法,但是这种方式只能读取xml中的数据,效率快,不占用太大内存。
3. dom4j这是有第三方提供的一种解析方式,我们需要去下载dom4j.jar才能进行使用,这种方式结合了前两种的一些优势,也是比较常用的一种解析方式。
一、dom对xml的基本操作
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<书架>
<书>
<书名>科学怪人</书名>
<作者>张三</作者>
<售价>20.0元</售价>
</书>
<书>
<书名>java</书名>
<作者>扎笑道</作者>
</书>
</书架>
下面这个例子就是简单操作xml的例子:
要求:对上面这个xml文件进行操作
package com.cn.ljh.jaxpxml;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class JaxpXml {
public static void main(String [] args) throws Exception{
//1、创建一个工厂类
DocumentBuilderFactory doucumentfactory = DocumentBuilderFactory.newInstance();
//2、创建一个解析器
DocumentBuilder builder = doucumentfactory.newDocumentBuilder();
Document document = builder.parse("src/Books.xml");
test7(document);
}
//1、在第一个元素上在增加一个子元素
public static boolean test1(Document document) throws Exception{
//先创建一个新的元素
Element element = document.createElement("内部价");
element.setTextContent("1元");
//获得父节点
Node node = document.getElementsByTagName("书").item(0);
//将新创建的节点添加上去
node.appendChild(element);
//将内存中的数据写入到硬盘
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/Books.xml"));
return true;
}
//2、在第一个元素的第一个子元素前面增加一个兄弟元素
public static boolean test2(Document document) throws TransformerException {
//创建一个新的元素
Element element = document.createElement("笔名");
element.setTextContent("大侠");
//获取插入位置的元素
Node node = document.getElementsByTagName("书名").item(0);
System.err.println(node.getTextContent());
node.insertBefore(element, node);
//node.appendChild(element);
//将内存中的数据写入到硬盘上
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
return true;
}
//3、删除第一个元素的第一个子元素
public static boolean test3(Document document) throws Exception{
//得到第一个节点
Node node = document.getElementsByTagName("内部价").item(0);
//获得父节点
node.getParentNode().removeChild(node);
//将内存中的数据写入硬盘中
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
return true;
}
//4、删除第一个元素
public static boolean test4(Document document){
Node node = document.getElementsByTagName("书").item(0);
node.getParentNode().removeChild(node);
TransformerFactory factory = TransformerFactory.newInstance();
try {
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
//5、在第二个元素上增加属性
public static void test5(Document document) throws Exception{
Node node = document.getElementsByTagName("书").item(0);
Element element = (Element) node;
element.setAttribute("出版社","四川出版社");
//将文件写入硬盘
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
}
//6、删除第一个元素的属性
public static void test6(Document document) throws Exception{
//获得第一个节点
Node node = document.getElementsByTagName("书").item(0);
Element element = (Element) node;
element.removeAttribute("出版社");
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
}
//7、增加一个新的完整的元素,这个元素有三个子元素,并且添加一个属性
public static void test7(Document document) throws Exception{
//创建一个新的元素
Element oneE = document.createElement("书");
Element towE = document.createElement("书名");
towE.setTextContent("java");
Element towW = document.createElement("作者");
towW.setTextContent("扎笑道");
//获取父节点(书架)
Node node = document.getFirstChild();
node.appendChild(oneE);
oneE.appendChild(towE);
oneE.appendChild(towW);
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
}
//8、获取第一个元素的第一个子元素的内容
public static boolean test8(Document document){
NodeList nodelist = document.getElementsByTagName("书名");
Node node = nodelist.item(0);
String name = node.getTextContent();
System.out.println(name);
return false;
}
//9、获取属性内容
public static void test9(Document document){
NodeList nodelist = document.getElementsByTagName("书");
Node node = nodelist.item(0);
Element element = (Element) node;
String attName = element.getAttribute("id");
System.out.println(attName);
}
//10、循环遍历打印标签内容
public static void test10(Node node){
//判断是不是Node类型
short type = node.getNodeType();
if(type == Node.ELEMENT_NODE){
System.out.println(node.getNodeName());
}
NodeList nodelist = node.getChildNodes();
long len = nodelist.getLength();
for(int i=0;i<len;i++){
Node n = nodelist.item(i);
test10(n);
}
}
//11、修改第一本书的书名的内容
public static boolean test11(Document document) throws Exception{
//得到第一本书
NodeList nodelist = document.getElementsByTagName("书名");
//得到第一本书的书名元素
Node node = nodelist.item(0);
node.setTextContent("商人");
//将内存中的数据写到硬盘上
TransformerFactory factory = TransformerFactory.newInstance();
factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
return true;
}
}
二、sax对xml的基本操作
<?xml version="1.0" encoding="UTF-8"?>
<movies>
<movie>
<name>捉妖记</name>
<time>2015</time>
<director>许诚毅</director>
</movie>
<movie>
<name>老炮儿</name>
<director>冯小刚</director>
<time>2016</time>
</movie>
</movies>
下面这个例子就是sax对xml的基本操作:
要求:对上面的xml文件进行内容读取,然后进行数据的封装
数据封装类
package com.cn.ljh.sax;
public class Movie {
private String name;
private String time;
private String director;
public Movie(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
}
sax操作类
package com.cn.ljh.sax;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class SaxTeat {
//现在要求将xml文档中的所有内容读取到movie中进行封装
public static void main(String[] args) throws Exception {
//下面就是sax解析xml的方式
//创建sax解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//创建sax的解析器
SAXParser parser = factory.newSAXParser();
//创建xml读取器
XMLReader reader = parser.getXMLReader();
List<Movie> movies = new ArrayList<Movie>();//存储电影数据
//挂载解析器(并实现解析其中的方法)
reader.setContentHandler(new DefaultHandler(){
Movie movie = null;
String tag = null;
//读取到元素开始,执行该方法
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
super.startElement(uri, localName, qName, attributes);
if("movie".equals(qName)){
movie = new Movie();
}
tag = qName;
}
//读取到元素结束,执行该方法
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if("movie".equals(qName)){
movies.add(movie);
}
}
//读取到内容,执行该方法
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
if("name".equals(tag)){
movie.setName(new String(ch,start,length));
}
if("time".equals(tag)){
movie.setTime(new String(ch, start, length));
}
if("director".equals(tag)){
movie.setDirector(new String(ch,start,length));
}
tag = null;
}
});
reader.parse("src/movie.xml");
for(Movie m : movies){
System.out.println(m.getName());
System.out.println(m.getDirector());
System.out.println(m.getTime());
}
}
}
可以看到上面,我没有去实现ContentHandler这个接口,我是去继承了DefaultHandler类,这里用到了适配器的设计模式(这样我们可以更加方便的去实现里面的方法)。同时我们也可以看出来,这个类中的方法就像是事件一样的方法,当解析器读到每一个标签或者内容都会触发这些方法,所以,这些方法需要自己去实现。同时,这样操作我们还需要将数据进行封装,这样方便我们以后的操作。
三、dom4j对xml的基本操作
<?xml version="1.0" encoding="UTF-8"?>
<cars>
<car time="2015">
<name>科鲁兹</name>
<color>白色</color>
<price>1500000</price>
<oil>10.L</oil>
</car>
<car where="中国">
<name>新蒙迪欧</name>
<price>1700000</price>
</car>
<car where="japan">
<name>丰田</name>
<color>黑色</color>
<price>1000000</price>
</car>
</cars>
下面这个例子就是dom4j对xml的基本操作
要求:对上面的xml文件进行一些简单的操作
package com.cn.ljh.Dom4j;
import java.io.FileWriter;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
public class Dom4jTest {
// 对cas这个xml文件进行操作,利用dom4j的方式
// 1.得到第一辆车的名字
@Test
public void test1() throws Exception {
SAXReader read = new SAXReader();
// 得到文档树
Document document = read.read("src/cars.xml");
// 得到根元素
Element root = document.getRootElement();
List<Element> elements = root.elements("car");
// 得到第一个car元素
Element e = elements.get(0);
// 得到name元素
Element name_E = e.element("name");
String name = name_E.getText();
System.out.println("name= " + name);
}
// 2.得到第二辆车的属性
@Test
public void test2() throws Exception {
// 得到读取器
SAXReader read = new SAXReader();
Document document = read.read("src/cars.xml");
// 得到根元素
Element root = document.getRootElement();
// 得到所有车的元素
List<Element> es = root.elements("car");
// 得到第二个车的元素
Element car2 = es.get(1);
Attribute att = car2.attribute("where");
String where = att.getText();
System.out.println("where=" + where);
}
// 3.得到第二辆车的价格
@Test
public void test3() throws Exception {
SAXReader read = new SAXReader();
Document document = read.read("src/cars.xml");
Element root = document.getRootElement();
List<Element> cars = root.elements("car");
Element car = cars.get(1);
// 得到价格
Element price = car.element("price");
String text = price.getText();
System.out.println(text);
}
// 4.添加第一辆车一个属性
@Test
public void test4() throws Exception {
SAXReader read = new SAXReader();
Document document = read.read("src/cars.xml");
Element root = document.getRootElement();
List<Element> cars = root.elements("car");
Element car = cars.get(0);
// 添加属性
car.addAttribute("time", "2015");
// 将内存中的数据写到硬盘上
XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
writer.write(document);
writer.close();
String text = car.attribute("time").getText();
System.out.println(text);
}
// 5.删除第一辆车的属性
@Test
public void test5() throws Exception {
SAXReader read = new SAXReader();
Document document = read.read("src/cars.xml");
Element root = document.getRootElement();
List<Element> cars = root.elements("car");
Element car = cars.get(0);
// 得到第一辆车的属性
Attribute att = car.attribute("where");
// 删除属性
car.remove(att);
// 将内存中的数据写入到硬盘上
XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
writer.write(document);
writer.close();
}
// 6.给第一辆车添加油耗元素
@Test
public void test6() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cars.xml");
Element root = document.getRootElement();
List<Element> cars = root.elements("car");
Element car = cars.get(0);
// 添加一个元素
car.addElement("oil").addText("10.L");
// 将数据写入到内存中
XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
writer.write(document);
writer.close();
}
// 7.删除第二辆车的颜色的元素
@Test
public void test7() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cars.xml");
Element root = document.getRootElement();
List<Element> cars = root.elements("car");
Element car = cars.get(1);
Element color = car.element("color");
car.remove(color);
// 将数据写入到硬盘上
XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
writer.write(document);
writer.close();
}
// 8.打印所有的标签内容和名字
@Test
public void test8() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read("src/cars.xml");
Element root = document.getRootElement();
//遍历所有元素
print(root);
}
//遍历所有元素的方法
private void print(Element element){
String text_name = element.getName();
String text = element.getText();
System.out.println("name = "+text_name+"text = "+text);
for(int i=0,size = element.nodeCount(); i < size;i++){
Node node = element.node(i);
if(node instanceof Element){
print((Element) node);
}
}
}
// 9.创建一个完整的car,包含属性
@Test
public void test9() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read("src/cars.xml");
Element root = document.getRootElement();
Element car = root.addElement("car")
.addAttribute("where", "japan");
car.addElement("name").addText("丰田");
car.addElement("color").addText("黑色");
car.addElement("price").addText("1000000");
//将内存中的数据写入到硬盘中
XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
writer.write(document);
writer.close();
}
}
那么上面这些例子只是简单的以dom4j的方式进行简单的操作,dom4j的功能还有非常多,当我们需要使用这种方式去操作一个xml的时候可以去研究官方文档。dom4j的操作方式要比上面的两种简单高效。
记录学习的每一步,记录每一次的成长!!!!