dom和sax分别是java对xml文档进行解析的方法
各有优缺点:dom缺点->占用内存大,优点->便于进行增加,删除,修改等操作
sax缺点->不易进行增加,删除,修改等操作,优点:一行行读取,速度快,省内存
贴上一段代码:【book.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架[
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
]>
<书架>
<书>
<书名>javaweb3.0</书名>
<作者>songjia</作者>
<售价>139.00</售价>
</书>
<书>
<书名>javaweb2.0</书名>
<作者>song</作者>
<售价>120.00</售价>
</书>
</书架>
java代码:
package day2;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Demo3 {
@Test
public void read() throws SAXException, IOException, ParserConfigurationException{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
NodeList list = document.getElementsByTagName("书名");
Node node = list.item(0);
String content = node.getTextContent();
System.out.println(content);
}
要解析到xml文档有三部曲:1创建解析器工厂DocumentBuilderFactory.newInstance();2由工厂创建解析器:factory.newDocumentBuilder ;3解析文档:builder.parse(文档名);
遍历 整个文档节点
@Test
public void read2() throws SAXException, IOException, ParserConfigurationException{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//得到根节点
Node root = document.getElementsByTagName("书架").item(0);
list(root);
}
private void list(Node root) {
// TODO Auto-generated method stub
if(root instanceof Element){
System.out.println(root.getNodeName());
}
NodeList list = root.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node child = list.item(i);
//System.out.println(child.getNodeName());
list(child);
}
}
list递归
在书中添加节点<售价>109.00</售价>
//为元素添加标签:书里<售价>109元</售价>
@Test
public void add() throws SAXException, IOException, ParserConfigurationException, TransformerException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//创建节点
Element e =document.createElement("售价");
e.setTextContent("109元");
//得到父节点
Element book = (Element) document.getElementsByTagName("书").item(0);
//把创建的节点加入到父节点中
book.appendChild(e);
//将更新后的内存写入原来的xml文档中
TransformerFactory tfactory =TransformerFactory.newInstance();
Transformer tranform=tfactory.newTransformer();
tranform.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
首先创建要添加的节点,设置节点值,然后得到父节点,用appendChild();方法来添加节点,但是别忘了将更新后的内存写入到原来的xmlwendang中去。另外还有一个insertbefore(newChild,referChild)可以将新节点插入到referChild节点之前。
更新节点值:所谓更新就是在原有的值得基础上来从新设置一个值,节点用setTEXTcontent方法,属性用setValue方法
//修改节点值
@Test
public void updata() throws ParserConfigurationException, SAXException, IOException, TransformerException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
Element name = (Element) document.getElementsByTagName("书名").item(0);
name.setTextContent("中国China");
TransformerFactory tfactory =TransformerFactory.newInstance();
Transformer tranform=tfactory.newTransformer();
tranform.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
//给元素添加属性<书名 name="wangming">..</书名>
@Test
public void addAtt() throws ParserConfigurationException, SAXException, IOException, TransformerException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
Element bookname = (Element) document.getElementsByTagName("书名").item(0);
bookname.setAttribute("name", "wangming");
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
删除节点:首先要得到节点,然后得到其父节点,用removeChild方法将其删除
@Test
public void deledeNode() throws ParserConfigurationException, SAXException, IOException, TransformerException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
Element price = (Element) document.getElementsByTagName("售价").item(0);
price.getParentNode().removeChild(price);
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
如果要想删除整个xml文档,可想而知,和删除节点一样,只不过把要删除的节点当成了根节点,用根节点的父亲去删除它。
可以看到这些这些代码中关于xnl读入和写出都是重复的,那我们为了减少代码,就会建立一个xmlUtils.java工具,类中方法都是静态方法即类方法,便于调用,如下:
public class XmlUtils {
private static String fileName="src/book.xml";
public static Document getDocument() throws Exception, Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new File(fileName));
}
public static void writeToXml(Document document) throws Exception {
// TODO Auto-generated method stub
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer t = tfactory.newTransformer();
t.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
}