JAXP解析XML(基于DOM模型)
2014-04-21 19:52
357 查看
对于XML解析通常分为两种:
1.DOM解析(Document Object Model,文档对象模型),该方式是W3C 组织推荐的处理 XML 的一种方式。
2.另一种是SAX(Simple API for XML)。
当然IBM公司后面退出了JAXB,基于JavaBean的XML解析方式,不过本文描述的是DOM模型解析原理以及使用Java内置的API(JAXP---Java API for XML Processing)通过DOM模型来解析XML,因为JAXP作为JavaEE规范中的一种技术,所以作为一个Java程序猿来说掌握这套API是必须的。
一:什么是DOM?
Document Object Model(文档对象模型),它是W3C 组织推荐的处理 XML 的一种方式。
DOM模型定义访问和操作XML文档的标准方法。(即定义一种访问XML文档一种规范)
下面来看一份XML文档:
这是一份有效(格式良好,且有DTD约束)的XML文档。
当我们使用DOM方式去解析该XML文档的时候,XML文档会在内存中形成一个树形结构,而XML 文档中的每个成分都是一个节点。
![](http://images.cnitblog.com/i/609421/201404/211927346702681.png)
这里特别要注意的是:
W3C组织对DOM是这样定义的:
整个文档是一个文档节点(Document)
XML中的每个标签都是元素节点(Element Node)
XML中的每个文本都是文本节点(Text Node)
XML中的标签属性都是属性节点(Attr Node)
XML中的注释被称为注释节点(Comment Node)
文本总是存储在文本节点中,而不是存储在元素节点中的,在 DOM 处理中一个普遍的错误是,认为元素节点包含文本。
不过,元素节点的文本是存储在文本节点中的。
在这个例子中:<year>2005</year>,元素节点 <year>,拥有一个值为 "2005" 的文本节点。
"2005" 不是 <year> 元素的值!
最后需要注意的是:由于解析器会将XML文档中的所有节点都加载到内存之中,所以可以很方便的完成CRUD操作,但是此方法也过于暴力,当XML文档内容过大时,可能会造成内存溢出的情况,这点大家都应该很清楚。
二:使用JAXP采用DOM编程模型解析XML.
解析XML的本质是通过解析器去完成的,但是我们并不是直接去调用解析器的方法去操作XML文档.而是SUN公司为我们提供了一套API让我们调用,与解析器交互的事情由SUN公司帮助我们完成.
1.DOM解析(Document Object Model,文档对象模型),该方式是W3C 组织推荐的处理 XML 的一种方式。
2.另一种是SAX(Simple API for XML)。
当然IBM公司后面退出了JAXB,基于JavaBean的XML解析方式,不过本文描述的是DOM模型解析原理以及使用Java内置的API(JAXP---Java API for XML Processing)通过DOM模型来解析XML,因为JAXP作为JavaEE规范中的一种技术,所以作为一个Java程序猿来说掌握这套API是必须的。
一:什么是DOM?
Document Object Model(文档对象模型),它是W3C 组织推荐的处理 XML 的一种方式。
DOM模型定义访问和操作XML文档的标准方法。(即定义一种访问XML文档一种规范)
下面来看一份XML文档:
<?xml version="1.0" encoding="UTF-8"?> <!--将DTD文件编写在XML文档内部--> <!DOCTYPE bookstore [ <!ELEMENT bookstore (book)+> <!ELEMENT book (title,author,year,price)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT year (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ATTLIST book category CDATA #REQUIRED> <!ATTLIST title lang CDATA #REQUIRED> ]> <bookstore> <book category="操作系统"> <title lang="中文">鸟哥的私房菜</title> <author>鸟哥</author> <year>2005</year> <price>89.5</price> </book> </bookstore>
这是一份有效(格式良好,且有DTD约束)的XML文档。
当我们使用DOM方式去解析该XML文档的时候,XML文档会在内存中形成一个树形结构,而XML 文档中的每个成分都是一个节点。
![](http://images.cnitblog.com/i/609421/201404/211927346702681.png)
这里特别要注意的是:
W3C组织对DOM是这样定义的:
整个文档是一个文档节点(Document)
XML中的每个标签都是元素节点(Element Node)
XML中的每个文本都是文本节点(Text Node)
XML中的标签属性都是属性节点(Attr Node)
XML中的注释被称为注释节点(Comment Node)
文本总是存储在文本节点中,而不是存储在元素节点中的,在 DOM 处理中一个普遍的错误是,认为元素节点包含文本。
不过,元素节点的文本是存储在文本节点中的。
在这个例子中:<year>2005</year>,元素节点 <year>,拥有一个值为 "2005" 的文本节点。
"2005" 不是 <year> 元素的值!
最后需要注意的是:由于解析器会将XML文档中的所有节点都加载到内存之中,所以可以很方便的完成CRUD操作,但是此方法也过于暴力,当XML文档内容过大时,可能会造成内存溢出的情况,这点大家都应该很清楚。
二:使用JAXP采用DOM编程模型解析XML.
解析XML的本质是通过解析器去完成的,但是我们并不是直接去调用解析器的方法去操作XML文档.而是SUN公司为我们提供了一套API让我们调用,与解析器交互的事情由SUN公司帮助我们完成.
package cn.plx.jaxp; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; 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.Attr; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * 使用SUN提供的JAXP解析XML文档 * * @author Administrator * */ public class JAXPTest { public static void main(String[] args) throws Exception { // 创建XML解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); /* * om.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl * xerces是由IBM公司提供的XML解析器 */ System.out.println(factory.getClass().getName()); // 创建XML解析器 DocumentBuilder builder = factory.newDocumentBuilder(); System.out.println(builder.getClass().getName()); /** * <pre> * 获取到Document对象,Document对象代表着DOM树的根节点 * 使用Document对象可以对XML文档的数据进行基本操作 * Document对象在DOM解析模型中也属于一个Node对象, * 它是其他Node对象所在的上下文,其他Node对象包括 * Element,Text,Attr,Comment,Processing Instruction等等 * 根节点 != 根元素,它们是包含关系 * </pre> */ Document document = builder.parse(new File("xml/book.xml")); /** * <pre> * 获取到XML文档的根元素 * 对于XML中的Document是XML文档的根节点,而它的子元素是XML文档的XML文档根元素 * </pre> */ Element root = document.getDocumentElement(); System.out.println("获取的XML文档的根元素节点:" + root.getTagName()); /** * <pre> * 获取根元素节点的子节点 * 对于XML文档而言,无论是Document,Elment,Text等等, * 它们在DOM解析模型中都属性一个Node,因此这里需要注意的一点是 * 空白字符在DOM解析中也会被作为一个Node元素来处理。 * </pre> */ // 获取到根元素的子节点 NodeList nodeList = root.getChildNodes(); /* * 空白字符也会被当作子节点来处理,因为它也是一个Node来处理, 但是属性不会被作为子节点 */ System.out.println("子节点的个数为:" + nodeList.getLength()); // 遍历所有的子节点 for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); switch (node.getNodeType()) { case Node.ELEMENT_NODE: System.out.println("获取的是元素:" + node.getNodeName()); break; case Node.TEXT_NODE: System.out.println("获取的是文本" + node.getNodeName()); break; case Node.COMMENT_NODE: System.out.println("获取的是注释:" + node.getNodeName()); Comment comment = (Comment) node; System.out.println("注释的内容是:" + comment.getData()); break; } } System.out.println("--------访问属性----------"); // 访问属性 Attr attr = root.getAttributeNode("名字"); System.out.println("根元素节点属性的值:" + attr.getValue()); // 可以是使用一种更加直接的方式访问属性的值 String attrValue = root.getAttribute("名字"); System.out.println("另一种方式获取根元素节点属性的值:" + attrValue); // 获取元素的全部属性 NamedNodeMap attrs = root.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { Attr attr2 = (Attr) attrs.item(i); System.out.println("name:" + attr2.getName() + ",value:" + attr2.getValue()); } } /** * <pre> * 使用JAXP完成添加元素节点操作 * 对于DOM解析模型来说,因为XML文档的上下文是Document对象 * 所以对于XML文档的操作都使用Document对象来完成 * </pre> */ @Test public void addElementTest() throws Exception { // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 获取XML文档的根节点(root node) Document document = builder.parse(new File("xml/book2.xml")); // 返回新创建的Element节点 Element book = document.createElement("书"); Element bookName = document.createElement("书名"); bookName.setTextContent("Liunx"); Element author = document.createElement("作者"); author.setTextContent("XXX"); Element price = document.createElement("价格"); price.setTextContent(String.valueOf(80.5)); // 通过父元素添加子元素 book.appendChild(bookName); book.appendChild(author); book.appendChild(price); document.getDocumentElement().appendChild(book); TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult( new File("xml/book2.xml"))); } /** * 更新节点元素 */ @Test public void updateElementTest() throws Exception { // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 获取XML文档的根节点(root node) Document document = builder.parse(new File("xml/book2.xml")); // 获取第3个价格元素 Node priceNode = document.getElementsByTagName("价格").item(2); // 判断是否是Element类型 if (priceNode.getNodeType() == Node.ELEMENT_NODE) { priceNode.setTextContent("200"); } TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult( new File("xml/book2.xml"))); } @Test public void deleteElementTest() throws Exception { // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 获取XML文档的根节点(root node) Document document = builder.parse(new File("xml/book2.xml")); Node node = document.getElementsByTagName("书").item(2); document.getDocumentElement().removeChild(node); TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult( new File("xml/book2.xml"))); } /** * 添加子元素到到指定位置 * @throws Exception */ @Test public void insertElementTest() throws Exception{ // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 获取XML文档的根节点(root node) Document document = builder.parse(new File("xml/book2.xml")); // 返回新创建的Element节点 Element book = document.createElement("书"); Element bookName = document.createElement("书名"); bookName.setTextContent("Liunx"); Element author = document.createElement("作者"); author.setTextContent("XXX"); Element price = document.createElement("价格"); price.setTextContent(String.valueOf(80.5)); // 通过父元素添加子元素 book.appendChild(bookName); book.appendChild(author); book.appendChild(price); document.getDocumentElement().insertBefore(book, document.getElementsByTagName("书").item(1)); TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult( new File("xml/book2.xml"))); } /** * 添加属性 * @throws Exception */ @Test public void addAttrTest() throws Exception{ // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 获取XML文档的根节点(root node) Document document = builder.parse(new File("xml/book2.xml")); Node node = document.getElementsByTagName("书").item(1); if(node.getNodeType() == Node.ELEMENT_NODE){ Element element = (Element) node; element.setAttribute("名称","Java开发"); } TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult( new File("xml/book2.xml"))); } }
相关文章推荐
- jaxp对xml文档进行dom解析并进行CRUD操作
- 用“XML解析开发包Jaxp”对XML进行Dom方式解析-readXml操作
- XML的dom和Sax解析,以及JAXP的DOM的crud
- XML系列:(4)XML解析-JAXP的DOM解析方式读取XML
- Sun公司的jaxp解析中的DOM解析与生成XML
- 使用JAXP对XML文档进行DOM解析
- JAXP对XML的DOM解析(增删改查)
- ADO.NET实体框架Entity Framework模型-基于XML解析
- 使用JAXP的DOM方式解析XML文档(能力工场)
- XML系列:(5)XML解析-JAXP的DOM解析方式修改XML
- 用DOM方式解析XML(使用JAXP工具)--第一天
- JAXP-DOM解析xml(CURD)
- 使用JAXP的DOM方式解析XML文档(能力工场)
- 用DOM方式解析XML(使用JAXP工具)--第一天
- 用DOM方式解析XML(用JAXP工具)--小案例---第一天
- java解析xml--DOM模型
- 【JAVA学习小结】-【用JAXP解析包解析XML方法】-【第一篇DOM解析】
- XML之DOM解析模型
- jaxp利用DOM解析XML
- xml的dom解析(jaxp实现)