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

自己写的一个用DOM方式处理xml的的工具类

阅读更多

    最近没事整理了下关于java dom的应用,包含的dom方式的解析、创建、修改、删除等操作。感觉应该是能给初学dom的同学们提供点参考。
    在写这个工具类的过程中我也发现了一些问题:比如要查找某个node节点下nodeName为version的子节点,是没有getElementByTagName方法的,很不方便,以致要修改某节点的内容的话,程序会写的很麻烦;还有一个问题就是,我删除了一个node节点后,在xml文档中,以前节点的位置成为了空行,这个空行我不知道怎么删除掉。
    能帮我解决这两个问题的朋友欢迎给我回帖! 

 

package com.yansirliu.common.xml;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
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.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * 用org.w3c.dom来处理xml文件
 * 
 * 本类中的transformXML(file)方法,可以在解析一切xml文件,并在控制台打印出来
 * 
 * @author yansirliu Mar 22, 201011:17:56 PM declaration:
 * 
 */

public class XMLDomUtil {

	/**
	 * 创建xml文档
	 */
	public void createXML(File file) throws Exception {

		// 解析器工厂类
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
				.newInstance();
		// 忽略空格
		documentBuilderFactory.setIgnoringElementContentWhitespace(true);
		// 解析器
		DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
		
		// xml对象
		Document doc = builder.newDocument();

		// 设置xml版本
		doc.setXmlVersion("1.0");

		// 创建根节点
		Element root = doc.createElement("books");

		// 为根节点添加属性
		root.setAttribute("type", "编程类");
		root.setAttribute("year", "2010");

		// 将根节点添加到document中去,root添加到doc中去后,后面再向root中添加子节点,对与doc同样生效
		doc.appendChild(root);

		/* 设置第一本书 */
		Element bookElement = doc.createElement("book");

		// 设置book节点的id属性
		bookElement.setAttribute("id", "001");

		// 设置name节点
		Element nameElement = doc.createElement("name");

		// 给method设置值
		nameElement.setTextContent("java编程思想");

		// 将method节点添加到page节点
		bookElement.appendChild(nameElement);

		// 创建company节点
		Element companyElement = doc.createElement("company");
		companyElement.setTextContent("清华大学出版社");
		bookElement.appendChild(companyElement);

		// 创建price节点
		Element priceElement = doc.createElement("price");
		priceElement.setTextContent("58.9");
		bookElement.appendChild(priceElement);

		// 将第一本书添加到根节点
		root.appendChild(bookElement);

		/* 设置第二本书 */
		Element bookElement2 = doc.createElement("book");

		// 设置book节点的id属性
		bookElement2.setAttribute("id", "002");

		// name节点
		Element nameElement2 = doc.createElement("name");
		nameElement2.setTextContent("JavaScript高级编程");

		bookElement2.appendChild(nameElement2);

		// company节点
		Element companyElement2 = doc.createElement("company");
		companyElement2.setTextContent("北京理工大学出版社");

		bookElement2.appendChild(companyElement2);

		// price节点
		Element priceElement2 = doc.createElement("price");
		priceElement2.setTextContent("66.5");

		bookElement2.appendChild(priceElement2);

		// 加到root节点
		root.appendChild(bookElement2);

		//保存
		this.saveDocument(doc, file);

	}

	/**
	 * 解析整个xml并打印出来
	 * 
	 * @param filePath
	 */
	public void transformXML(File file) throws Exception {

		Document doc = this.getDocument(file);

		// 取出根节点
		Element root = doc.getDocumentElement();

		// 解析打印该节点及所有子节点
		this.transformNode(root, "");

	}
	
	/**
	 * 为已有的xml文档增加节点
	 * @param filePath
	 */
	public void addNode(File file) throws Exception{
		
		//得到已有的book.xml对象,为其增加几个节点
		Document doc = this.getDocument(file);
		
		//根节点
		Element root = doc.getDocumentElement();
		
		//先为已经有的两个book节点添加version节点
		NodeList list = root.getElementsByTagName("name");
		
		//java编程思想为第一版
		Element version = doc.createElement("version");
		version.setTextContent("第一版");
		//JavaScript高级编程为第四版
		Element version2 = doc.createElement("version");
		version2.setTextContent("第二版");
		
		//为book节点增加version节点
		int length = list.getLength();
		for(int i=0;i<length;i++){
			Node node = list.item(i);
			if (node.getTextContent().trim().equals("java编程思想".trim())) {
				node.getParentNode().appendChild(version);
			}else if (node.getTextContent().trim().equals("JavaScript高级编程".trim())) {
				node.getParentNode().appendChild(version2);
			}
		}
		
		//新增一个book节点
		Element book = doc.createElement("book");
		book.setAttribute("id", "003");
		
		Element name = doc.createElement("name");
		name.setTextContent("ExtJS入门教程");
		Element company = doc.createElement("company");
		company.setTextContent("机械工业出版社");
		Element price = doc.createElement("price");
		price.setTextContent("34.5");
		Element version3 = doc.createElement("version");
		version3.setTextContent("第一版");
		
		book.appendChild(name);
		book.appendChild(company);
		book.appendChild(price);
		book.appendChild(version3);
		
		root.appendChild(book);
		
		//保存
		this.saveDocument(doc, file);
		
	}
	
	/**
	 * 修改节点
	 * 我靠,dom方式的修改真的是很麻烦
	 * @param file
	 * @throws Exception
	 */
	public void modifyNode(File file) throws Exception{
		/*
		 *将java的售价提高5元,JavaScript减少2元,ExtJS增加11.5元 
		 */
		
		Document doc = this.getDocument(file);
		
		//先取得所有NodeName为name的节点
	    NodeList nameList = doc.getElementsByTagName("name");
	    int length = nameList.getLength();
	    //为了尽量减少循环设此变量
	    int count = 0;
	    //循环判断
	    for(int i=0;i<length && count < 3;i++){
	    	Node node = nameList.item(i);
	    	if(node.getTextContent().trim().equals("java编程思想".trim())){
	    		node = node.getParentNode();
	    		node = node.getLastChild();
	    		
	    		//当node节点不为空且node名称不为price时,不停向上面一个节点查找,直到上面在也没有节点
	    		while(node != null && !node.getNodeName().equals("price")){
	    			node = node.getPreviousSibling();
	    		}
	    		if(node!=null && node.getNodeName().trim().equals("price".trim())){
	    			String sPrice = this.getString(node.getTextContent());
					double price = Double.parseDouble(sPrice);
					price = price + 5;
					node.setTextContent(new Double(price).toString());
	    		}
	    		//修改完一本后记录数加一次
	    		count++;
	    	}
	    	if(node.getTextContent().trim().equals("JavaScript高级编程".trim())){
	    		node = node.getParentNode();
	    		node = node.getLastChild();
	    		
	    		while(node != null && !node.getNodeName().equals("price")){
	    			node = node.getPreviousSibling();
	    		}
	    		if(node!=null && node.getNodeName().trim().equals("price".trim())){
	    			String sPrice = this.getString(node.getTextContent());
					double price = Double.parseDouble(sPrice);
					price = price - 2;
					node.setTextContent(new Double(price).toString());
	    		}
	    		//修改完一本后记录数加一次
	    		count++;
	    	}
	    	if(node.getTextContent().trim().equals("ExtJS入门教程".trim())){
	    		node = node.getParentNode();
	    		node = node.getLastChild();
	    		
	    		//当node节点不为空且node名称不为price时,不停向上面一个节点查找,直到上面在也没有节点
	    		while(node != null && !node.getNodeName().equals("price")){
	    			node = node.getPreviousSibling();
	    		}
	    		if(node!=null && node.getNodeName().trim().equals("price".trim())){
	    			String sPrice = this.getString(node.getTextContent());
					double price = Double.parseDouble(sPrice);
					price = price + 11.5;
					node.setTextContent(new Double(price).toString());
	    		}
	    		//修改完一本后记录数加一次
	    		count++;
	    	}
	    }
		
		this.saveDocument(doc, file);
		
	}
	
	/**
	 * 删除node节点,当node被删除后,xml文件中会出现空行,我还不知道怎样去掉这些空行
	 * @param file
	 * @throws Exception
	 */
	public void deleteNode(File file) throws Exception{
		/*
		 * 删除所有nodeName为verion的节点
		 */
		Document doc = this.getDocument(file);
		
		NodeList list = doc.getElementsByTagName("version");

		/*
		 * NodeList特性:当其中包含的node被父节点删除后,NodeList也会随之将之删除,NodeList的length减少1,排序靠后的node会依次
		 * 向前移动,占据被移除的node的位置
		 * 下面循环中只要NodeList的长度还大于0,便继续循环,始终删除处于0位置的node
		 */
		for(int i=0;list.getLength()>0;){
			Node node = list.item(i); 
			node.getParentNode().removeChild(node);
		}
		
		this.saveDocument(doc, file);
	}
	

	/**
	 * 递归方法,解析一个Node及其子Node并打印出来
	 * 
	 * @param Node
	 *            要解析的的节点
	 * @param space
	 *            第一个节点距离页面最左端的空格
	 * @throws Exception
	 */
	public void transformNode(Node node, String space) throws Exception {

		// 判断该Node对象是否为Element
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			// 格式用空格,子节点头部与父节点相差几个空格
			String addSpace = "    ";

			// 先打印该节点名称及属性
			String head = this.getNodeNameAndAttribute(node, space);
			System.out.print(head);

			// 判断该节点是否有ELEMENT_NODE类型子节点,如果再调用本方法递归
			boolean check = this.checkChildNodes(node);
			if (check) {
				// 如果有子节点,则要换行显示了
				System.out.println();
				// 得到子节点
				NodeList list = node.getChildNodes();
				int length = list.getLength();
				for (int i = 0; i < length; i++) {
					Node childNode = list.item(i);
					this.transformNode(childNode, space + addSpace);
				}
			} else {
				String content = node.getTextContent();
				if (content.trim().length() > 0) {
					System.out.print(content);
				}
			}

			// 打印该节点的尾部信息,为了打印TextContent时没有多余的空格要进行判断
			// 子节点校验为true时这样打印
			if (check) {
				System.out.println(space + "<" + node.getNodeName() + "/>");
			}
			// 子节点校验为false时这样打印
			else {
				System.out.println("<" + node.getNodeName() + "/>");
			}

		}
	}

	/**
	 * 解析每个开始节点的名称及属性
	 * 
	 * @param node
	 *            要解析的节点
	 * @param space
	 *            子节点换行时加几个空格以助显示
	 * @return 该节点的xml方式显示
	 */
	public String getNodeNameAndAttribute(Node node, String space) {

		StringBuffer buffer = new StringBuffer();
		// 加入打头空格
		buffer.append(space);
		// 节点名
		buffer.append("<" + node.getNodeName());
		// 解析根节点属性
		if (node.hasAttributes()) {
			NamedNodeMap map = node.getAttributes();
			for (int i = 0; i < map.getLength(); i++) {
				node = map.item(i);
				buffer.append(" " + node.getNodeName() + "=\""
						+ node.getNodeValue() + "\"");
			}
			buffer.append(">");
		} else {
			buffer.append(">");
		}
		return buffer.toString();
	}

	/**
	 * 判断一个节点是否含有最少一个ELEMENT_NODE类型的子节点
	 * 
	 * @param node
	 * @return true表示该节点含有子节点且至少有一个子节点是ELEMENT_NODE类型的
	 *         false表示该节点没有子节点或子节点全不是ELEMENT_NODE类型的
	 */
	public boolean checkChildNodes(Node node) {
		boolean check = false;
		if (node.hasChildNodes()) {
			NodeList list = node.getChildNodes();
			int length = list.getLength();
			for (int i = 0; i < length && check == false; i++) {
				if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
					check = true;
				}
			}
		}
		return check;
	}

	/**
	 * 过滤null、"null"
	 * @param s
	 * @return
	 * @throws Exception
	 */
	public String getString(String s) throws Exception{
		if(s == null || s.trim().equals("null") || s.trim().length()<1){
			return "";
		}else{
			return s.trim().toString();
		}
	}
	
	/**
	 * 通过dom提供的document解析工厂得到document
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public Document getDocument(File file) throws Exception{

		// 解析器工厂类
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
				.newInstance();
		// 忽略空格
		documentBuilderFactory.setIgnoringElementContentWhitespace(true);
		// 解析器
		DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();

		// xml对象
		Document doc = builder.parse(file);
		
		return doc;
	}
	
	/**
	 * 保存生成或修改完的xml文件
	 * @param doc
	 * @param file
	 * @throws Exception
	 */
	public void saveDocument(Document doc,File file) throws Exception{
		
		// 开始把Document映射到文件
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();

		// 设置输出结果
		DOMSource source = new DOMSource(doc);

		// 判断文件是否存在,如不存在则创建
		if (!file.exists()) {
			file.createNewFile();
		}

		// 设置输入源
		Result xmlResult = new StreamResult(file);

		// 输出xml文件
		transformer.transform(source, xmlResult);
	}
	
	/*
	 * 在main方法中找到你自己存放xml文件的地址,把filepath修改下就可以了
	 */
	public static void main(String[] args) throws Exception {

		// 获取工程的绝对路径
		String projectRealPath = System.getProperties().getProperty("user.dir");
		String xmlFoderPath = projectRealPath + "\\WebRoot\\xml";
		String filePath = xmlFoderPath + "\\" + "book.xml";
		File file = new File(filePath);
		
		
		//调用下面几个方法可以创建xml,添加节点,删除节点,修改内容,解析xml
		
		//new XMLDomUtil().createXML(file);
                               //new XMLDomUtil().addNode(file);
//		new XMLDomUtil().deleteNode(file);
		//new XMLDomUtil().modifyNode(file);
//		new XMLDomUtil().transformXML(file);
		
	}
}

 

附上用create方法生成的xml文件

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<books type="编程类" year="2010">
	<book id="001">
		<name>java编程思想</name>
		<company>清华大学出版社</company>
		<price>58.9</price>
	</book>
	<book id="002">
		<name>JavaScript高级编程</name>
		<company>北京理工大学出版社</company>
		<price>66.5</price>
	</book>
</books>

  

 

 

1
0
分享到:
评论

相关推荐

    自己写的一个dom4j解析xml文件工具类

    自己写的一个dom4j解析xml文件工具类

    xml-dom4j解析工具类

    分析这个项目可以帮助我们更深入地理解如何在实际开发中使用DOM4J和自定义工具类来处理XML数据。例如,我们可以看到如何加载XML文件,如何调用上述方法来获取所需信息,以及如何处理返回的结果。 总的来说,XML-DOM...

    DOM4J xml解析工具

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活、高性能的API,使得开发者可以方便地读取、写入、修改以及查询XML数据。DOM4J的名字来源于Document Object Model (DOM) 和 Java的结合,但它并不局限于...

    dom4j 工具类 使用例子

    在这个"dom4j工具类使用例子"中,我们将深入探讨如何利用DOM4J进行XML处理。 首先,`Dom4jUtil.java`可能是包含DOM4J实用方法的类。这个类可能包括了创建、查询、修改XML文档的各种静态方法。例如,可能会有用于...

    java Dom4j 无敌连环解析XML工具类

    在本教程中,我们将深入探讨如何使用DOM4J来解析XML文件,并创建一个无敌连环解析工具类。 首先,我们需要了解XML的基本概念。XML(可扩展标记语言)是一种标记语言,常用于数据交换和存储。它的结构化特性使其非常...

    Dom4jUtils 工具类让你更加方便操作XML的MarkerIce.Jar

    总结来说,`Dom4jUtils`工具类是DOM4J库的一个便利扩展,它提供了一系列便捷的方法来处理XML文件。在`MarkerIce.jar`这个特定的上下文中,`Dom4jUtils`可能用于XML配置的读取、解析和更新,从而简化了在Ice框架中的...

    读写超大类xml文件,使用dom4j读写xml文件的工具类

    基于dom4j的读写xml文件的工具包。封装了dom4j操作xml文档的常和方法。 支持两种读写方法。1:针对小文件的读取整个文档,2:针对大文件的,逐行读取。读到几百M文件毫无压力。

    java一键xml转map,一键map转xml工具类

    本文将详细讲解如何使用Java实现XML到Map以及Map到XML的一键转换,并介绍一个已封装好的工具类`EasyXmlUtil`。 首先,XML到Map的转换涉及到XML的解析。在Java中,我们可以使用`javax.xml.parsers....

    dom4j读写xml文档实例

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了简单且高效的API来读取、写入、修改以及操作XML。在这个实例中,我们将深入理解DOM4J库如何帮助我们处理XML文档,并通过实际操作来熟悉其核心功能。 XML...

    dom4j 工具类

    DOM4J是一个强大的Java XML API,它提供了全面的XML处理功能,包括解析、操作和生成XML文档。DOM4J在Java社区中被广泛使用,因其简洁的API和高效的性能而受到青睐。在这个文档中,我们将深入探讨DOM4J的核心概念和...

    利用DOM读写XML

    在处理XML时,DOM(Document Object Model)是一种常用的方法,它将XML文档解析为一个树形结构,使得我们可以方便地访问和修改XML文档的每一个部分。 DOM模型的核心是DOMDocument对象,它是整个XML文档的根节点,...

    dom4j工具类

    **DOM4J工具类详解** DOM4J是一个强大的Java XML处理库,它提供了一套灵活且功能丰富的API,使得在Java应用程序中解析、创建、修改XML文档变得异常简单。DOM4J的名字来源于“DOM for Java”,它是一个基于DOM模型的...

    一次代码重构之旅-快速读写xml文件工具类封装

    在IT行业中,代码重构是一项重要的技能,它有助于提高...总之,这次重构之旅旨在通过创建一个高效的XML工具类,提高代码的可复用性和性能。对于任何需要处理XML数据的Java开发者来说,这是一个值得学习和借鉴的案例。

    xml解析工具类

    本教程将详细介绍一个名为"WXML"的XML解析工具类,该工具类能便捷地将XML数据转换为Java对象,从而简化开发流程。 首先,XML解析分为两种主要方式:DOM(Document Object Model)和SAX(Simple API for XML)。DOM...

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

    DOM4J是一个Java库,提供了更灵活和高效的XML处理功能,相比DOM,DOM4J提供了更丰富的API和更好的性能。它同样基于DOM模型,但提供了更友好的接口,适合处理大型XML文件。 3. **DOM4J解析步骤**: - 引入DOM4J库...

    Dom4j写XML和读取XML的工具类,非常好用

    "Dom4j写XML和读取XML的工具类,非常好用" 这个标题表明我们要讨论的是一个使用Dom4j库来处理XML文档的Java工具类。Dom4j是一个非常流行的Java库,它提供了XML的解析、创建、修改以及查询功能,使得在Java中操作XML...

    基于XStream,DOM4J实现xml工具类可直接运行

    在提供的压缩包“xmlPro”中,可能包含了一系列示例代码或工具类,展示了如何集成XStream和DOM4J,以便在实际项目中高效地处理XML数据。 总的来说,理解和熟练掌握XStream和DOM4J对于Java开发人员来说非常重要,...

    XML解析工具类

    XML(eXtensible Markup Language)是一...总之,这个“XML解析工具类”是一个便捷的资源,提供了多种XML解析方式,适用于不同的场景和需求。不论你是初学者还是经验丰富的开发者,都能从中受益,更高效地处理XML数据。

    一个用DOM4J来读取XML的工具类

    这个工具类"XmlHandle"显然是为了方便开发者使用DOM4J来读取XML文件。 首先,DOM4J的核心概念包括Document、Element、Attribute、Namespace等。Document代表整个XML文档,Element是XML中的元素节点,Attribute表示...

Global site tag (gtag.js) - Google Analytics