声明:本文是观看传智播客方立勋视频的学习过程,非常详细,做一点总结。
一:在解析xml文档对象以前,需要获得文档对象。这部分是模版代码
//1:创建工厂,使应用程序能够从 XML 文档获取生成 DOM 对象树的解析器 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //2:得到dom解析器 DocumentBuilder builder = factory.newDocumentBuilder(); //3:解析xml文档,得到代表文档的document Document doc = builder.parse("src/Book.xml");
其中很多对文档操作后,需要更新文档的部分也是模版代码。
//把跟新后的内存写会到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml")));
当然这些代码应该放在一个工具类,但是也懒得做了,下面的代码显得臃肿了一些。
二:获得了文档对象以后,就是对文档的CRUD过程。
先说一句十分重要的话:XML文档中的类容会有对应的对象 :标签ELEMENT对象,文本变为Text对象,还有属性Attri对象。但不管是什么对象,都是Node的子类,所以在开发中可以把获取到的任意节点都当做Node看待。合适的转换很重要。
文档添加:
a:添加节点
//添加节点 @Test public void add() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); //创建节点 Element price = doc.createElement("售价"); price.setTextContent("59.00"); //把创建的节点挂到第一本书上 Element book = (Element) doc.getElementsByTagName("书").item(0); book.appendChild(price); //把跟新后的内存写回到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml"))); }
这里面注意的是添加节点以后,要将更新后的内存写回到文档
b:将节点添加到指定的位置上
//向文档中指定位置添加节点 @Test public void add2() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); //创建节点 Element price = doc.createElement("售价"); price.setTextContent("59.00"); //得到参考节点 Element refnode = (Element) doc.getElementsByTagName("售价").item(0); //得到要挂仔的节点 Element book = (Element) doc.getElementsByTagName("书").item(0); //插入 book.insertBefore(price, refnode); //把跟新后的内存写会到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml"))); }
c:添加属性
[java] view plaincopy //向文档中添加属性 @Test public void addAttribute() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); Element element = (Element) doc.getElementsByTagName("书名").item(0); element.setAttribute("name", "xxxx"); //把跟新后的内存写会到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml"))); }
读取文档:
a:得到指定标签的内容
@Test public void Read1() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); NodeList list = doc.getElementsByTagName("书名"); Node node = list.item(1);//从0开始 String content = node.getTextContent(); System.out.println(content); }
b:遍历所有的标签,这里面使用的递归。
@Test public void Read2() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); //得到根节点 Node root = doc.getElementsByTagName("书架").item(0); list(root);//递归打印 } private void list(Node node) { if(node instanceof Element){ System.out.println(node.getNodeName()); } NodeList list = node.getChildNodes(); for(int i=0;i<list.getLength();i++){ Node child = list.item(i); list(child); } }
c:得到指定标签的属性,这里面使用了Node--->Eelement的转换
@Test public void Read3() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); Element node = (Element) doc.getElementsByTagName("书名").item(0); String value = node.getAttribute("name"); System.out.println(value); }
3:删除:
@Test public void delete() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); //得到要删除的节点 Element e = (Element) doc.getElementsByTagName("售价").item(0); //得到要删除节点的父节点 Element book = (Element) e.getParentNode(); //删除 book.removeChild(e);//或者e.getParentNode().removeChild(e); //把跟新后的内存写会到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml"))); }
4:更改
@Test public void update() throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("src/Book.xml"); //得到要更新的节点 Element e = (Element) doc.getElementsByTagName("售价").item(0); //把跟新后的内存写会到文档 TransformerFactory tffactory = TransformerFactory.newInstance(); Transformer tf = tffactory.newTransformer(); tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("src/Book.xml"))); }
三:总结
通过上面的代码演示,可以感到到模版代码比较多。就是固定的获得文档,写回文档。
然后重要的亮点重复一下:
1:XML文档中的类容会有对应的对象:标签ELEMENT对象,文本变为Text对象,还有属性Attri对象。但不管是什么对象,都是Node的子类,所以在开发中可以把获取到的任意节点都当做Node看待。
2:递归遍历所有的标签。
实例
import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.junit.BeforeClass; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @author forlab * @version 2012-12-19 */ public class Dom { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void readXml() throws ParserConfigurationException, SAXException, IOException{ DocumentBuilderFactory db = DocumentBuilderFactory.newInstance(); DocumentBuilder dbuilder = db.newDocumentBuilder(); Document dom = dbuilder.parse("src/dom.xml"); Node node = dom.getElementsByTagName("书架").item(0); list(node); } private void list(Node node) { if(node instanceof Element){ System.out.println(node.getNodeName()); } NodeList nodes = node.getChildNodes(); for(int i=0;i<nodes.getLength();i++){ Node child = nodes.item(i); list(child); } } @Test public void readXmlByAttrubuteName() throws ParserConfigurationException, SAXException, IOException{ DocumentBuilderFactory db = DocumentBuilderFactory.newInstance(); DocumentBuilder dbuilder = db.newDocumentBuilder(); Document dom = dbuilder.parse("src/dom.xml"); Element element = (Element) dom.getElementsByTagName("作者").item(0); System.out.println(element.getAttribute("name")); } }