`
and4walker
  • 浏览: 563927 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

DOM

    博客分类:
  • XML
阅读更多
DOM(Document Object Model):W3C组织推荐的处理XML的标准接口.
http://www.w3.org/DOM/DOMTR.html

DOM特点:首先将整个XML文档读取到内存中才能进行某些操作,如果XML文档很大,则会影响性能。

DOM结构模型:
DOM的核心概念就是NODE(节点).DOM在分析XML文档时,将组成XML文档的各个部分(元素,属性,文本,注释,处理指令等)映射成一个对象,这个对象就叫做节点。在内存中这些节点形成一棵树。整棵树就是一个节点,树中的每一个节点也是一棵树。
DOM就是对这棵树的一个对象描述,我们通过访问树中的节点来存取XML文档的内容。

DOM解析器工厂:javax.xml.parsers.DocumentBuilderFactory
第一种使用其系统属性的方式:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
第二种使用其系统属性的方式:
java -Djava.xml.parsers.DocumentBuilderFactory = oracle.xml.jaxp.JXDocumentBuilderFactory DOMTest
第三种方式:
如果不想使用JDK默认的解析器,比如使用apache的Xerces解析器,只需建立JRE\lib\endorsed目录,然后将xercesImpl.jar文件copy到其目录下。

DOM树中的节点类型:
DOM本质上是节点的集合。由于一个文档中可能包含不同类型的信息,因此要定义不同类型的节点。XML中最常见的节点类型:文档,元素,文本,属性,其他不常用的节点类型包括:注释,处理指令,文档类型,CDATA段,文档片段,实体,实体引用,记号。
文档节点:文档树的根节点,也是文档中其他所有节点的父节点。但是不是根元素,因为XML文档中注释,处理指令等可以出现在根元素之外,所以在构造DOM树时,根元素并不适合作为根节点,于是就有了文档节点。根元素则作为文档节点的子节点。文档节点通过org.w3c.dom.Document接口来实现。
元素节点:XML文档中的元素。通常元素拥有子元素,文本节点或两者结合。元素节点也是唯一能够拥有属性的节点类型。该节点通过org.w3c.dom.Element接口来实现。
文本节点:只包含文本内容(在XML中称为字符数据)的节点,它可以由更多信息组成,也可包含空白。在文档树中元素跟属性的文本内容都是由文本节点来表示的。该节点通过org.w3c.dom.Text接口来实现,Text接口继承CharacterData接口。
属性节点:元素中的属性。属性实际上是附属元素的,所以属性节点不能被看作是元素的子节点,即属性没有被认为是文档树的一部分,例如在属性节点上调用getParentNode(),getPreviousSibling()和getNextSibling()返回都是NULL。
也就是说属性节点被看作包含他的元素节点的一部分,它并不作为单独的一个节点在文档树中出现。该节点通过org.w3c.dom.Attribute接口来实现。
注释节点:该节点通过org.w3c.dom.Comment接口来实现。
处理指令节点:表示XML文档中的处理指令。该节点通过org.w3c.dom.ProcessingInstruction接口来实现。
文档类型节点:每一个Document都有一个doctype属性,其值炜null或DocumentType对象。该节点通过org.w3c.dom.DocumentType接口来实现。
CDATA段节点表示XML文档中的CDATA段。该节点通过org.w3c.dom.CDAT
ASection接口来实现。该接口继承自Text接口。
实体节点:XML文档中已分析或未分析实体。该节点通过org.w3c.dom.Entity接口来实现。
实体引用节点:DOM树中的一个实体引用。该节点通过org.w3c.dom.EntityReference接口来实现。
记号节点:在DTD中声明的记号。该节点通过org.w3c.dom.Notation接口来实现。


NodeList接口:提供了一个有序节点集合的抽象。该方法下定义了两个方法:
1.int getLength():该方法返回列表中节点的数目。
2.Node item(int index):该方法返回集合中指定索引的节点。集合中的索引从0开始。
注意:DOM中的NodeList对象是动态的。eg.使用Node接口的getChildNodes()得到一个节点的子节点列表,然后你调用insertBefore(),appendChild(),replaceChild()和removeChild()等任何一个方法,都将影响到NodeList对象,也就是说此时再调用getLength()和item()将返回与先前不同的值。

org.w3c.dom.NamedNodeMap接口:也是节点的集合。通过该接口可以建立节点名跟节点之间的一一映射,从而利用节点名直接访问对应的节点。
注意:该接口无序。并不是继承自NodeList接口。并且该接口也是动态的。
eg.在某个元素节点上调用getAttributes()将返回一个包含属性名和属性节点映射的NamedNodeMap对象。

DOM实例一:得到文本节点的内容
students.xml
<?xml version="1.0" encoding="gb2312"?>

<?xml-stylesheet type="text/xml" href="students.xsl">

<students>
  <student sn="01">
     <name>张三</name>
     <age>11</age>
  </student>
  <student sn="02">
     <name>李四</name>
     <age>14</age>
  </student>
</students>

java类:DOMStudentInfo.java
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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;

public class DOMStudentInfo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new File("students.xml"));
			NodeList nl = doc.getElementsByTagName("student");
			int len = nl.getLength();
			for(int i=0;i<len;i++){
				Element eltStu = (Element)nl.item(i);
				Node eltName = eltStu.getElementsByTagName("name").item(0);
				Node eltAge = eltStu.getElementsByTagName("age").item(0);
				//注意:此时不能用eltName.getNodeValue()得到“张三”的值
				//因为"张三"这个文本节点是name的子节点,所以得调用
				//eltName.getFirstChild().getNodeValue()来得到"张三"的值
				System.out.println("name:"+eltName.getFirstChild().getNodeValue());
				System.out.println("age:"+eltAge.getFirstChild().getNodeValue());
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

DOM实例二:循环遍历文档中的所有NODE
java类:DOMPrinter.java
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;


public class DOMPrinter {

	public void printNodeInfo(Node node){
		System.out.println(node.getNodeName()+":"+node.getNodeValue());
	}
	
	public void printNode(Node node){
		short nodeType = node.getNodeType();
		switch(nodeType){
			case Node.PROCESSING_INSTRUCTION_NODE:
				System.out.println("=====指令节点开始=====");
				System.out.println(node);
				System.out.println("=====指令节点结束=====");
				break;
			case Node.ELEMENT_NODE:
				System.out.println("=====元素节点开始=====");
				System.out.println(node);
				System.out.println("=====元素节点结束=====");
				//得到元素节点的全部属性
				NamedNodeMap attrs = node.getAttributes();
				int attrNum = attrs.getLength();
				for(short i=0;i<attrNum;i++){
					Node attr = attrs.item(i);
					System.out.println("=====元素节点的属性开始=====");
					printNodeInfo(attr);
					System.out.println("=====元素节点的属性结束=====");
				}
				break;
			case Node.TEXT_NODE:
				System.out.println("=====文本节点的属性开始=====");
				printNodeInfo(node);
				System.out.println("=====文本节点的属性结束=====");
				break;
			default:
				break;
		}
		Node child  = node.getFirstChild();
		while(null != child){
			printNode(child);
			child = child.getNextSibling();
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new File("students.xml"));
			DOMPrinter domPrinter = new DOMPrinter();
			domPrinter.printNode(doc);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

DOM实例三:在节点树中添加/删除节点,xml转换
java类:DOMConvert.java
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.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class DOMConvert {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new File("students.xml"));
			//创建元素节点
			Element eltStu = doc.createElement("student");
			Element eltName = doc.createElement("name");
			Element eltAge = doc.createElement("age");
			//创建文本节点
			Text textName = doc.createTextNode("王五");
			Text textAge = doc.createTextNode("19");
			//创建元素节点与文本节点的关系
			eltName.appendChild(textName);
			eltAge.appendChild(textAge);
			//创建元素节点之间的关系
			eltStu.appendChild(eltName);
			eltStu.appendChild(eltAge);
			//设定最外层元素节点的属性
			eltStu.setAttribute("sn", "03");
			//上面只是添加跟students平行的树节点
			//如果想在students下面建立必须先得到students的元素节点
			Element root = doc.getDocumentElement();
			root.appendChild(eltStu);
			//删除“张三”的节点树
			NodeList nl = root.getElementsByTagName("student");
			root.removeChild(nl.item(0));
			//此时NodeList为动态的,“李四”成为第一个树节点
			//修改“李四”节点的年龄为65
			Element eltStuChg = (Element)nl.item(0);
			Node nodeAgeChg = eltStuChg.getElementsByTagName("age").item(0);
			nodeAgeChg.getFirstChild().setNodeValue("65");
			//打印出来
			int len = nl.getLength();
			for(int i=0;i<len;i++){
				Element elt = (Element)nl.item(i);
				System.out.println("编号:"+elt.getAttribute("sn"));
				Node nodeName = elt.getElementsByTagName("name").item(0);
				Node nodeAge = elt.getElementsByTagName("age").item(0);
				String name = nodeName.getFirstChild().getNodeValue();
				String age = nodeAge.getFirstChild().getNodeValue();
				System.out.println("姓名:"+name);
				System.out.println("年龄:"+age);
				System.out.println("=====================");
			}
			//此时想将一个xml文件复制到另一个xml文件中,两种方案:
			//1.直接读取内容然后再生成;2.调用TransformerFactory
			//此时存在一个缺点就是不是well-formed
			TransformerFactory tff = TransformerFactory.newInstance();
			Transformer tf = tff.newTransformer();
			tf.setOutputProperty("encoding", "gb2312");
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File("converted.xml"));
			tf.transform(source,result);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
		
	}

}

DOM实例四:获取XML文档声明信息
hr.xml
<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE hr PUBLIC "-//xin sun//DTD HR 1.0//ZH" 
                    "hr.dtd"
[
<!ENTITY name "人力资源">
]>

<hr>&name;</hr>

hr.dtd
<!ELEMENT hr (#PCDATA)>
<!ENTITY % entitiesDecl SYSTEM "entity.dtd">
%entitiesDecl;

entity.dtd
<!NOTATION gif SYSTEM "image/gif">
<!NOTATION jpg SYSTEM "iexplore.exe">

<!ENTITY logo SYSTEM "http://orz.iteye.com/logo.gif" NDATA gif>
<!ENTITY banner SYSTEM "http://orz.iteye.com/banner.gif" NDATA jpg>

DOMDocTypePrinter.java:
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Entity;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Notation;
import org.xml.sax.SAXException;


public class DOMDocTypePrinter {

	public static void main(String[] args) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse("hr.xml");
			DocumentType docType = doc.getDoctype();
			if(null != docType){
				System.out.println("dtd 名称:"+docType.getName());
				System.out.println("dtd 公共标识符:"+docType.getPublicId());
				System.out.println("dtd 系统标识符:"+docType.getSystemId());
				System.out.println("dtd 内部子集:"+docType.getInternalSubset());
				System.out.println("============================");
				NamedNodeMap entities = docType.getEntities();
				int len = entities.getLength();
				for(int i=0;i<len;i++){
					Entity entity = (Entity)entities.item(i);
					System.out.println("实体名称:"+entity.getNodeName());
					System.out.println("记号名称:"+entity.getNotationName());
					System.out.println("实体公共标识符:"+entity.getPublicId());
					System.out.println("实体系统标识符:"+entity.getSystemId());
					System.out.println("============================");
				}
				NamedNodeMap notations = docType.getNotations();
				len = notations.getLength();
				for(int i=0;i<len;i++){
					Notation notation = (Notation)notations.item(i);
					System.out.println("记号名称:"+notation.getNodeName());
					System.out.println("记号公共标识符:"+notation.getPublicId());
					System.out.println("记号系统标识符:"+notation.getSystemId());
					System.out.println("============================");
				}
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
分享到:
评论

相关推荐

    DOM4J jar包 xml解析 所有的dom4j-1.6.1 dom4j-2.0.2 dom4j-2.1.1包 导入直接使用

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、修改和查询变得简单。DOM4J的名字来源于“Document Object Model for Java”,它采用面向对象的设计思想,提供了对...

    firefox DOM Inspector 火狐 dom 查看器插件 天涯浪子

    DOM Inspector是Mozilla Firefox的一个扩充套件,官方中文版上称之为DOM观察器,在安装Mozilla Firefox时,可以在自订安装中选择是否安装DOM Inspector,如果在安装Mozilla Firefox时没有选择自订安装以安装DOM ...

    dom4j_dom4j1.6.1安装包_

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活、高效的API,使得XML的解析、创建、查询和修改变得更为简单。在本文中,我们将深入探讨DOM4J 1.6.1版本的安装及其在Maven项目中的应用。 首先,DOM4J...

    xml 三种解析方式dom,sax,dom4j

    为了处理XML文档,有三种主要的解析方式:DOM、SAX和DOM4J。每种方法都有其特点和适用场景,下面将详细介绍这三种解析方式。 1. DOM(Document Object Model) DOM解析器将整个XML文档加载到内存中,构建一个树形...

    使用dom4j 和本地dom 解析xml 文件

    在Java中,解析XML文件是常见的任务,通常有DOM(Document Object Model)和DOM4J两种方式。下面我们将详细探讨这两种解析方法。 DOM解析方式是将整个XML文件加载到内存中,形成一棵DOM树,每个节点代表XML文档的一...

    dom4j_1.6.1.jar dom4j_2.1.0.jar

    标题提及的"dom4j_1.6.1.jar"和"dom4j_2.1.0.jar"是两个不同版本的DOM4J库的Java档案文件,DOM4J是一个非常流行的Java XML API,用于处理XML文档。这两个版本的差异在于功能、性能优化和可能存在的bug修复。描述中...

    dom4j-1.6.1 与 dom4j-2.0.0-ALPHA

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活、高效的API,使得XML的解析、创建、修改和查询变得简单。这次我们有两个版本的DOM4J库:1.6.1和2.0.0-ALPHA。这两个版本在功能、性能和API设计上都有所...

    XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较,超详细

    常见的 XML 解析器有 DOM、SAX、JDOM 和 DOM4J 等。每种解析器都有其特点和优缺,选择合适的解析器对应用程序的性能和开发效率有很大影响。 1. DOM 解析器 DOM(Document Object Model)是 W3C 官方标准,用于表示...

    DOM和BOM的使用

    DOM 和 BOM 的使用 DOM(Document Object Model)和 BOM(Browser Object Model)是前端开发中两个基础概念。DOM 是一个文档对象模型,它将 HTML 文档抽象为一个树形结构,允许开发者通过 JavaScript 操作文档的...

    dom4j 2.1.1

    DOM4J 2.1.1 是一个针对Java平台的高效、开源的XML处理库,其全称为“Document Object Model for Java”。这个库提供了一系列强大的API,使得开发人员能够轻松地解析、创建、修改和操作XML文档。XML(eXtensible ...

    dom4j-2.1.1-API文档-中文版.zip

    赠送jar包:dom4j-2.1.1.jar; 赠送原API文档:dom4j-2.1.1-javadoc.jar; 赠送源代码:dom4j-2.1.1-sources.jar; 赠送Maven依赖信息文件:dom4j-2.1.1.pom; 包含翻译后的API文档:dom4j-2.1.1-javadoc-API文档-...

    dom4j解析xml文件的压缩包

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、查询和修改变得简单。这个压缩包包含了DOM4J的完整版本,适用于那些希望在Java项目中使用DOM4J进行XML操作的开发者...

    谷歌获取网页dom的插件

    在IT领域,尤其是在Web开发和数据抓取方面,"谷歌获取网页DOM的插件"是一种非常实用的工具。DOM(Document Object Model)是HTML和XML文档的结构化表示,它将网页内容作为树形结构处理,使得我们可以方便地通过...

    dom4j-2.1.1-API文档-中英对照版.zip

    赠送jar包:dom4j-2.1.1.jar; 赠送原API文档:dom4j-2.1.1-javadoc.jar; 赠送源代码:dom4j-2.1.1-sources.jar; 赠送Maven依赖信息文件:dom4j-2.1.1.pom; 包含翻译后的API文档:dom4j-2.1.1-javadoc-API文档-...

    dom4j-2.0.3.zip

    《深入解析DOM4J——基于Java的XML处理框架》 DOM4J,作为一个强大的Java XML API,是处理XML文档的主流工具之一。它提供了一套简单而高效的方式来操作XML文档,包括读取、写入、修改和遍历XML结构。在Java开发中,...

    DOM4J 的使用

    DOM4J 的使用 DOM4J 是一个开源的 XML 解析包,由 dom4j.org 出品,应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM、SAX 和 JAXP。DOM4J 的主要特点是使用大量的接口,所有主要接口都在 org.dom4j 里面定义...

    simple_html_dom,php下的html文件DOM解析库

    3. **遍历DOM**:可以轻松地遍历DOM树,获取元素、属性等信息。 4. **修改DOM**:可以添加、删除、修改HTML元素及其属性。 5. **提取数据**:支持提取文本、HTML、属性值等数据。 三、基本用法 1. **加载HTML**...

    解决vue页面DOM操作不生效的问题

    在Vue框架中,页面动态更新是非常常见的需求,但有时候开发者可能会遇到在页面上进行DOM操作不生效的问题。这种情况通常发生在某些数据更新之后,但直接进行DOM操作时,并没有取得预期效果。Vue使用的是虚拟DOM...

    js_HTML_Dom操作练习

    7. **DOM事件与DOM变化**:DOM提供了一些事件,如`DOMContentLoaded`,当文档加载完成后触发;还有`MutationObserver`接口,可以监听并响应DOM的变化。 8. **表格操作**:在HTML中,`&lt;table&gt;`元素及其子元素(`&lt;tr&gt;...

Global site tag (gtag.js) - Google Analytics