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

dom4j 对xml节点的增、删、改 操作

    博客分类:
  • xml
阅读更多

 

需求:

     在jsp页面上展示树形结构,当选中某个节点时,可以新增该节点的子节点、删除该节点、修改该节点信息。

     操作节点的时候,既操作数据库,也操作xml文件。先操作数据库,后操作xml文件。

     如果操作数据库失败,则不再操作xml文件。

 

说明:

      1. menuNo 是唯一的;

      2. 节点层次只有一层,但是各个节点之间有关联关系。如:menuNo=1 的子节点以“1-”(不包括双引号)

           开头;

      3. 在新增节点时,节点编号menuNo自动生成(查找数据库中menuNo的最大值,在此基础上加1);

      4. 这里只写对xml文件的操作,不写数据库操作。

 

环境说明:

    jdk-6u21;

jar 包:

     dom4j-1.6.1.jar;

     jaxen-1.1.4.jar;

     log4j-1.2.16.jar;

     slf4j-api-1.4.3.jar;

     slf4j-log4j12-1.4.0.jar

 

XML 文件:

<?xml version="1.0" encoding="UTF-8"?>

<root>
  <menu id="8a8080fd45d529340145d5294acf0000">
    <menuId>8a8080fd45d529340145d5294acf0000</menuId>
    <menuNo>1</menuNo>
    <parentNo>123</parentNo>
    <menuName>首页</menuName>
    <menuUrl>/home</menuUrl>
    <menuLevel>1</menuLevel>
    <isLeaf>0</isLeaf>
    <expanded>1</expanded>
    <loaded>1</loaded>
  </menu>
  <menu id="8a8080fd45d52b520145d52b64c30000">
    <menuId>8a8080fd45d52b520145d52b64c30000</menuId>
    <menuNo>1-1</menuNo>
    <parentNo>1</parentNo>
    <menuName>首页1</menuName>
    <menuUrl>index/index/homePage</menuUrl>
    <menuLevel>2</menuLevel>
    <isLeaf>1</isLeaf>
    <expanded>1</expanded>
    <loaded>1</loaded>
  </menu>
  <menu id="92e0b82fae0f4bbbaf7f478031d59b1f">
    <menuId>92e0b82fae0f4bbbaf7f478031d59b1f</menuId>
    <menuNo>1-2</menuNo>
    <parentNo>1</parentNo>
    <menuName>首页2</menuName>
    <menuUrl>index/index1</menuUrl>
    <menuLevel>2</menuLevel>
    <isLeaf>1</isLeaf>
    <expanded>1</expanded>
    <loaded>1</loaded>
  </menu>
  <menu id="8a8080fd45dea7320145dea755cd0000">
    <menuId>8a8080fd45dea7320145dea755cd0000</menuId>
    <menuNo>2</menuNo>
    <parentNo/>
    <menuName>系统管理</menuName>
    <menuUrl/>
    <menuLevel>1</menuLevel>
    <isLeaf>0</isLeaf>
    <expanded>1</expanded>
    <loaded>1</loaded>
  </menu>
  <menu id="8a8080fd45dea92f0145dea942bf0000">
    <menuId>8a8080fd45dea92f0145dea942bf0000</menuId>
    <menuNo>2-1</menuNo>
    <parentNo>2</parentNo>
    <menuName>菜单配置管理</menuName>
    <menuUrl>hw/menu</menuUrl>
    <menuLevel>2</menuLevel>
    <isLeaf>1</isLeaf>
    <expanded>1</expanded>
    <loaded>1</loaded>
  </menu>
</root>

 

其中,“首页1” 和 “首页2” 是 “首页” 的子节点;“菜单配置管理” 是 “系统管理” 的子节点;

 

需要用一个 JavaBean 来表示菜单节点:

HwMenu.java

public class HwMenu {

	private String menuId;
	// 菜单编号 (Unique Key)
	private String menuNo;
	// 菜单名称
	private String menuName;
	// 菜单链接
	private String menuUrl;
	// 菜单等级
	private String menuLevel;
	// 父编号 (对应 menuNo)
	private String parentNo;
	// 是否子节点. 0 : false , 1 : true
	private Integer isLeaf;
	// 是否展开. 0 : false , 1 : true
	private Integer expanded;
	// 是否加载. 0 : false , 1 : true
	private Integer loaded;

	// 省略getter/setter
}

 

xml节点处理类:

MenuTree.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MenuTree {

	private static final Logger log = LoggerFactory.getLogger(MenuTree.class);

	private static final String XML_FILE = "xml/menu.xml";

	/**
	 * @Title: addNode
	 * @deprecated: 将节点menu添加到xml文件中
	 * @param menu
	 *            : 节点信息
	 * @throws Exception
	 * @author 
	 * @date 2014-5-9
	 */
	public void addNode(HwMenu menu) throws Exception {

		XMLWriter xmlwriter = null;
		InputStream is = null;
		OutputStream out = null;

		try {
			SAXReader sax = new SAXReader();

			// 创建一个 menu 元素
			Element elt = DocumentHelper.createElement("menu");
			// 主键id
			Element menuId = DocumentHelper.createElement("menuId");
			// 菜单编号
			Element menuNo = DocumentHelper.createElement("menuNo");
			// 父编号
			Element parentNo = DocumentHelper.createElement("parentNo");
			// 菜单名称
			Element menuName = DocumentHelper.createElement("menuName");
			// 菜单链接
			Element menuUrl = DocumentHelper.createElement("menuUrl");
			// 菜单等级
			Element menuLevel = DocumentHelper.createElement("menuLevel");
			// 是否子节点
			Element isLeaf = DocumentHelper.createElement("isLeaf");
			// 是否展开
			Element expanded = DocumentHelper.createElement("expanded");
			// 是否加载
			Element loaded = DocumentHelper.createElement("loaded");

			menuId.setText(menu.getMenuId());
			menuNo.setText(menu.getMenuNo());
			parentNo.setText(menu.getParentNo());
			menuName.setText(menu.getMenuName());
			menuUrl.setText(menu.getMenuUrl());
			menuLevel.setText(menu.getMenuLevel());
			// 是否子节点. 0 : false , 1 : true
			isLeaf.setText(menu.getIsLeaf() + "");
			// 是否展开. 0 : false , 1 : true
			expanded.setText(menu.getExpanded() + "");
			// 是否加载. 0 : false , 1 : true
			loaded.setText(menu.getLoaded() + "");

			is = Thread.currentThread().getContextClassLoader()
					.getResourceAsStream(XML_FILE);

			Document doc = sax.read(is);

			// 根节点
			Element root = doc.getRootElement();

			// 将子元素添加到 menu 元素中
			elt.add(menuId);
			elt.add(menuNo);
			elt.add(parentNo);
			elt.add(menuName);
			elt.add(menuUrl);
			elt.add(menuLevel);
			elt.add(isLeaf);
			elt.add(expanded);
			elt.add(loaded);

			// 为 menu 添加 id 属性
			elt.addAttribute("id", menu.getMenuId());

			// 将menu元素添加到根节点下
			root.add(elt);

			// 输出格式
			OutputFormat outformat = new OutputFormat();
			// 指定XML编码
			outformat.setEncoding("UTF-8");
			outformat.setNewlines(true);
			outformat.setIndent(true);
			outformat.setTrimText(true);

			String rootPath = System.getProperty("user.dir");

			out = new FileOutputStream(rootPath + "/src-config/" + XML_FILE);

			xmlwriter = new XMLWriter(out, outformat);

			xmlwriter.write(doc);

		} catch (DocumentException e) {
			log.error("Add Node fail:" + e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			log.error("Add Node fail:" + e.getMessage(), e);
			throw e;
		} finally {
			close(xmlwriter, out, is);
		}
	}

	/**
	 * @Title: modifyNode
	 * @deprecated: 修改节点元素值
	 * @param menu
	 *            元素值
	 * @author 
	 * @date 2014-5-12
	 */
	@SuppressWarnings("rawtypes")
	public void modifyNode(HwMenu menu) throws Exception {

		InputStream is = null;
		OutputStream out = null;
		XMLWriter xmlwriter = null;

		Document doc = null;

		try {
			SAXReader sax = new SAXReader();

			is = Thread.currentThread().getContextClassLoader()
					.getResourceAsStream(XML_FILE);

			doc = sax.read(is);

			// 根节点
			Element root = doc.getRootElement();

			// 取得某节点下名为"menu"的所有字节点
			List nodes = root.elements("menu");

			// xml元素
			Element element = null;

			for (Object obj : nodes) {
				element = (Element) obj;
				// 修改指定节点下的子节点的值
				if (menu.getMenuId().equals(element.attributeValue("id"))) {
					element.element("menuId").setText(menu.getMenuId());
					element.element("menuNo").setText(menu.getMenuNo());
					element.element("parentNo").setText(menu.getParentNo());
					element.element("menuName").setText(menu.getMenuName());
					element.element("menuUrl").setText(menu.getMenuUrl());
					element.element("menuLevel").setText(menu.getMenuLevel());
					element.element("isLeaf").setText(menu.getIsLeaf() + "");
					element.element("expanded")
							.setText(menu.getExpanded() + "");
					element.element("loaded").setText(menu.getLoaded() + "");
				}
			}

			// 输出格式
			OutputFormat outformat = new OutputFormat();
			// 指定XML编码
			outformat.setEncoding("UTF-8");
			outformat.setNewlines(true);
			outformat.setIndent(true);
			outformat.setTrimText(true);

			String rootPath = System.getProperty("user.dir");

			out = new FileOutputStream(rootPath + "/src-config/" + XML_FILE);

			xmlwriter = new XMLWriter(out, outformat);

			xmlwriter.write(doc);

		} catch (DocumentException e) {
			log.error("Modify Node fail:" + e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			log.error("Modify Node fail:" + e.getMessage(), e);
			throw e;
		} finally {
			close(xmlwriter, out, is);
		}
	}

	@SuppressWarnings("rawtypes")
	public void removeNode(String nodeId) throws Exception {

		InputStream is = null;
		OutputStream out = null;
		XMLWriter xmlwriter = null;

		Document doc = null;

		try {
			SAXReader sax = new SAXReader();

			is = Thread.currentThread().getContextClassLoader()
					.getResourceAsStream(XML_FILE);

			doc = sax.read(is);

			// 根节点
			Element root = doc.getRootElement();

			// 取得某节点下名为"menu"的所有字节点
			List nodes = root.elements("menu");

			// xml元素
			Element element = null;
			Map<String, String> map = new ConcurrentHashMap<String, String>();

			for (Object obj : nodes) {
				element = (Element) obj;
				// 菜单编号
				String menuNo = null;
				// 删除指定节点下的子节点的值
				if (nodeId.equals(element.attributeValue("id"))) {

					menuNo = element.element("menuNo").getTextTrim();

					map.put("p_menuNo", menuNo);
					// 删除nodeId对应的菜单节点
					element.detach();
				}

				// 节点编号
				menuNo = element.element("menuNo").getTextTrim();

				if (null != map.get("p_menuNo")
						&& !"".equals(map.get("p_menuNo"))) {

					if (null != menuNo
							&& menuNo.startsWith(map.get("p_menuNo")
									.concat("-"))) {
						/* menuNo是 p_menuNo 的子节点 */
						// 删除子节点
						element.detach();
					}
				}
			}

			// 输出格式
			OutputFormat outformat = new OutputFormat();
			// 指定XML编码
			outformat.setEncoding("UTF-8");
			outformat.setNewlines(true);
			outformat.setIndent(true);
			outformat.setTrimText(true);

			String rootPath = System.getProperty("user.dir");

			out = new FileOutputStream(rootPath + "/src-config/" + XML_FILE);

			xmlwriter = new XMLWriter(out, outformat);

			xmlwriter.write(doc);

		} catch (DocumentException e) {
			log.error("Modify Node fail:" + e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			log.error("Modify Node fail:" + e.getMessage(), e);
			throw e;
		} finally {
			close(xmlwriter, out, is);
		}
	}

	private void close(XMLWriter xmlwriter, OutputStream out, InputStream is) {

		if (null != xmlwriter) {
			try {
				xmlwriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			xmlwriter = null;
		}

		if (null != out) {
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			out = null;
		}

		if (null != is) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			is = null;
		}
	}
}

 

如果是放在 web 工程中,则代码:

String rootPath = System.getProperty("user.dir");

 需要改成

HttpServletRequest req = ......

String rootPath = req.getSession().getServletContext().getRealPath("\\");

 

测试类(Junit 4):

MenuTreeTest.java

import org.junit.Test;

public class MenuTreeTest {

	@Test
	public void testAddNode() {

		HwMenu menu = new HwMenu();

		menu.setMenuId("8a8080fd45dea92f0145dea942bf0000");
		menu.setMenuNo("2-1");
		menu.setParentNo("2");
		menu.setMenuName("菜单配置管理");
		menu.setMenuUrl("hw/menu");
		menu.setMenuLevel("2");
		// 是否子节点. 0 : false , 1 : true
		menu.setIsLeaf(1);
		// 是否展开. 0 : false , 1 : true
		menu.setExpanded(1);
		// 是否加载. 0 : false , 1 : true
		menu.setLoaded(1);

		try {
			new MenuTree().addNode(menu);

			System.out.println("添加成功");

		} catch (Exception e) {
			System.out.println("添加失败");
			e.printStackTrace();
		}
	}

	@Test
	public void testModifyNode() {

		HwMenu menu = new HwMenu();

		menu.setMenuId("8a8080fd45d529340145d5294acf0000");
		menu.setMenuNo("1");
		menu.setParentNo("123");
		menu.setMenuName("首页");
		menu.setMenuUrl("/home");
		menu.setMenuLevel("1");
		// 是否子节点. 0 : false , 1 : true
		menu.setIsLeaf(0);
		// 是否展开. 0 : false , 1 : true
		menu.setExpanded(1);
		// 是否加载. 0 : false , 1 : true
		menu.setLoaded(1);

		try {
			new MenuTree().modifyNode(menu);

			System.out.println("更新成功");

		} catch (Exception e) {
			System.out.println("更新失败");
			e.printStackTrace();
		}
	}

	@Test
	public void testRemoveNode() {

		String nodeId = "8a8080fd45dea92f0145dea942bf0000";

		try {
			new MenuTree().removeNode(nodeId);

			System.out.println("删除成功");

		} catch (Exception e) {
			System.out.println("删除失败");
			e.printStackTrace();
		}
	}

}

 

代码结构:



 

  • 大小: 18.3 KB
分享到:
评论

相关推荐

    dom4j操作xml的增删改查

    本教程将详细讲解如何使用DOM4J进行XML的增、删、改、查操作。 **一、XML的基本概念** XML(eXtensible Markup Language)是一种标记语言,用于描述数据结构,通常用于存储和传输数据。DOM(Document Object Model...

    使用DOM4J对XML文件操作-添加、修改、删除、获取元素节点

    在本教程中,我们将深入探讨如何使用DOM4J来执行基本的XML操作,包括添加元素、修改元素、删除元素以及获取元素节点。 1. **添加元素节点** 在DOM4J中,添加元素节点通常涉及创建一个新的`Element`对象,然后将其...

    dom4j 解析(读取) xml 节点数据

    在本教程中,我们将深入探讨如何使用DOM4J解析(读取)XML节点数据,不受XML层级的限制。 首先,确保你已经下载了必要的依赖,即DOM4J库。通常,这将是一个名为`dom4j-x.x.x.jar`的文件,其中x.x.x是DOM4J的版本号...

    Xml完全操作 XML增删改查

    在Java中,我们可以使用DOM(Document Object Model)解析器将整个XML文档加载到内存中的树形结构中,便于遍历和操作。另一种解析方式是SAX(Simple API for XML),它采用事件驱动模型,逐行处理XML,节省内存但不...

    Dom4j对xml文件做增删改查(使用分层思想)

    在这个案例中,我们将深入探讨如何利用Dom4j实现XML文档的增删改查操作,并遵循分层架构的思想来组织代码。 **一、Dom4j解析XML** 1. **解析XML文档**:Dom4j通过`DocumentBuilderFactory`和`DocumentBuilder`来...

    dom4j 包含例子 各种增删改查

    这个压缩包包含了DOM4J的1.6.1版本,以及相关的示例代码,展示了如何进行XML的各种操作,如增、删、改、查(CRUD)。 在XML CRUD操作中,"Create"代表创建XML文档。DOM4J允许开发者动态地创建XML结构。例如,可以...

    dom4j解析xml详解

    12. **Node**: 为DOM4J中的所有XML节点提供一个多态接口,包括`Element`、`Attribute`、`Comment`等,简化了节点类型的处理。 13. **NodeFilter**: 定义了节点过滤器的行为,可以在遍历节点时应用条件筛选。 14. **...

    java DOM解析xml操作大全,增删改查

    Java中的DOM解析是处理XML文档的一种常见方法,它将整个XML文档加载到内存中,形成一个树形结构,便于对XML进行全方位的操作,包括增、删、改、查。在这个"java DOM解析xml操作大全,增删改查"的主题中,我们将深入...

    dom4j操作xml

    在本文中,我们将深入探讨DOM4J如何进行XML操作,包括增加、删除和修改XML元素。 首先,我们需要理解XML的基本结构。XML(可扩展标记语言)是一种用于存储和传输数据的标准格式,它使用标签来描述数据。DOM4J通过...

    Dom4J生成XML的完整方法希望大家能用到

    Dom4J作为一款优秀的Java XML API,以其简洁、高效的特点,在生成、解析和操作XML文档方面表现突出。本文将深入探讨如何使用Dom4J库来创建XML文档,包括初始化文档、添加元素、设置属性、插入文本以及最终保存文档至...

    dom4j解析xml文件的压缩包

    这个压缩包包含了DOM4J的完整版本,适用于那些希望在Java项目中使用DOM4J进行XML操作的开发者。 首先,让我们深入了解一下DOM4J的核心概念和特性: 1. **Document对象**:DOM4J中的Document对象代表整个XML文档。...

    使用Maven管理项目,实现DOM4j操作XML文件

    DOM4j则是一个强大的Java库,用于处理XML文档,提供了丰富的API来实现XML的读取、写入、修改等操作。在这个示例中,我们将深入探讨如何利用Maven管理和DOM4j来操作XML文件。 首先,让我们了解一下Maven。Maven是...

    dom4j读写xml文档实例

    在这个实例中,我们将深入理解DOM4J库如何帮助我们处理XML文档,并通过实际操作来熟悉其核心功能。 XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于数据交换、配置文件、文档存储等领域。...

    Qt5 XML文件的解析,增删改查节点。

    本篇文章将深入探讨Qt5如何使用DOM(Document Object Model)模型来操作XML文件,实现增、删、改、查功能。 首先,让我们了解Qt5中的QDomDocument类。QDomDocument是DOM模型的核心,它代表了一个完整的XML文档。你...

    dom4j解析XML所需jar包

    5. **XML文档操作**:DOM4J提供了丰富的API,如添加、删除、移动和复制XML节点,以及修改节点内容和属性值。这些功能使得对XML文档的维护和更新变得非常方便。 6. **XPath和XSLT转换**:除了基本的XML操作,DOM4J还...

    dom4j解析xml

    ### DOM4J解析XML知识点详解 ...通过结合使用DOM4J的基本类和XPath表达式,可以轻松地实现对XML文档的查询和修改。无论是对于开发人员还是对于那些需要频繁处理XML数据的应用程序来说,DOM4J都是一个非常有价值的工具。

    winform对xmL的增删改查

    本示例中,"winform对xmL的增删改查"实现了在WinForm应用程序中对XML文件的操作,包括添加数据、删除数据、修改数据以及查询数据。以下是关于这些操作的详细解释: 1. **XML文件的读取**: - 使用`System.Xml`命名...

    JAVA 操作 XML 增删改查

    3. DOM4J库:DOM4J是基于DOM的Java库,提供了一种更简洁的方式来操作XML,包括增删改查。例如,使用`Element`类的`addAttribute`、`removeAttribute`、`getText()`、`setText()`方法进行操作。 从"源码 工具"标签,...

    java dom4j解析xml

    Java DOM4J解析XML是一种常见的处理XML文档的技术,它提供了灵活且高效的API,使得开发者能够方便地读取、写入、修改以及操作XML文件。DOM4J是Java中一个非常强大的XML处理库,它结合了DOM、SAX和JDOM的优点,同时也...

Global site tag (gtag.js) - Google Analytics