sax解析實現xml增刪改
阿新 • • 發佈:2019-01-31
需求:
在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.javapublic 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();
}
}
}