XML解析

做了一个XML的工具,满足一下常用的功能,如果有什么问题,欢迎指点。
XPath,感觉用起来还是非常顺手的,非常简单的选择器,非常的好用。
XPath语法:http://www.w3school.com.cn/xpath/xpath_syntax.asp

package com.acgist.utils;
 
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.xml.sax.InputSource;
 
/**
 * 读取和操作XML文件 这个类只适合读取没有命名空间的xml
 */
public class XmlUtils {
    private String path; // 文件路径
    private Document document; // XML的document
 
    /**
     * 初始化xmlTools
     */
    public XmlUtils() {
    }
 
    /**
     * 加载工具
     * @param path xml地址
     * @return 工具
     */
    public static XmlUtils loadXml(String path) {
        XmlUtils xmlUtils = new XmlUtils();
        SAXReader saxReader = new SAXReader();
        try {
            xmlUtils.path = path;
            xmlUtils.document = saxReader.read(new File(path));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return xmlUtils;
    }
     
    /**
     * 加载XML
     * @param content xml内容
     * @return 工具
     */
    public static XmlUtils loadContent(String content) {
        XmlUtils xmlUtils = new XmlUtils();
        SAXReader saxReader = new SAXReader();
        try {
            xmlUtils.document = saxReader.read(new InputSource(new ByteArrayInputStream(content.getBytes("UTF-8"))));
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return xmlUtils;
    }
 
    /**
     * 设置XML的document
     * @param document xml文档
     */
    public void setDocument(Document document) {
        this.document = document;
    }
 
    /**
     * 设置XML的路径
     * @param path xml路径
     */
    public void setPath(String path) {
        this.path = path;
    }
     
    /**
     * @param doc 文档
     * @param xmlPath xPath路径 /xx/xx
     * @return 内容 节点内容
     */
    public String getValue(String xmlPath) {
        List<?> nodes = this.document.selectNodes(xmlPath);
        Iterator<?> iterator = nodes.iterator();
        String value = null;
        while (iterator.hasNext()) {
            Element elm = (Element) iterator.next();
            value = elm.getText();
            break;
        }
        return value;
    }
     
    /**
     * 读取所有的节点
     * @param xPath xPath 
     * @return 节点内容集合
     */
    public List<String> getValues(String xPath){
        List<?> nodes = this.document.selectNodes(xPath);
        Iterator<?> iterator = nodes.iterator();
        List<String> texts = new ArrayList<String>();
        while (iterator.hasNext()) {
            Element elm = (Element) iterator.next();
            texts.add(elm.getText());
        }
        return texts;
    }
     
    /**
     * 选取节点
     * @param xPath xPath
     * @return 节点集合
     */
    public List<?> getNodes(String xPath) {
        return this.document.selectNodes(xPath);
    }
     
    /**
     * 选取节点,还有命名空间,默认命名空间为default
     * @param xmlPath xPath:/default:musics/default:music
     * @return 节点集合
     */
    public List<?> getNodesWithNameSpance(String xmlPath) {
        Map<String, String> namespances = new HashMap<String, String>();
        String defaultNamespace = this.document.getRootElement().getNamespaceURI();
        namespances.put("default", defaultNamespace);
        XPath xPath = this.document.createXPath(xmlPath);
        xPath.setNamespaceURIs(namespances);
        return xPath.selectNodes(this.document);
    }
 
    /**
     * @param doc 文档
     * @param xmlPath xPath路径 制度去第一个属性的值
     * @return 属性内容
     */
    public String getAttributeValue(String xmlPath, String name) {
        List<?> nodes = this.document.selectNodes(xmlPath);
        Iterator<?> iterator = nodes.iterator();
        String value = null;
        while (iterator.hasNext()) {
            Element elm = (Element) iterator.next();
            value = elm.attributeValue(name);
            break;
        }
        return value;
    }
     
    /**
     * @param doc 文档
     * @param xmlPath xPath路径 制度去第一个属性的值
     * @return 属性内容
     */
    public String getAttributeValueWithNameSpance(String xmlPath, String name) {
        Map<String, String> namespances = new HashMap<String, String>();
        String defaultNamespace = this.document.getRootElement().getNamespaceURI();
        namespances.put("default", defaultNamespace);
        XPath xPath = this.document.createXPath(xmlPath);
        xPath.setNamespaceURIs(namespances);
        List<?> nodes = xPath.selectNodes(this.document);
        Iterator<?> iterator = nodes.iterator();
        String nodeText = null;
        while (iterator.hasNext()) {
            Element elm = (Element) iterator.next();
            nodeText = elm.attributeValue(name);
            break;
        }
        return nodeText;
    }
 
    /**
     * 指定节点添加节点
     * @param xxPath 指定节点选择器
     * @param name 节点名称
     * @param attributes 节点的属性
     * @param text 节点内容
     */
    public void add(String xxPath, String name, Map<String, String> attributes, String text) {
        Element parent = (Element) this.document.selectSingleNode(xxPath);
        Element element = parent.addElement(name);
        if(StringUtils.isNotEmpty(text))
            element.setText(text);
        if (attributes != null) {
            Set<String> set = attributes.keySet();
            for (String key : set) {
                element.addAttribute(key, attributes.get(key));
            }
        }
    }
     
    /**
     * 更新XML文档
     * 
     * @param xmlPath 选择器xPath
     * @param text 更新的内容
     * @param attributes 更新的属性
     */
    public void update(String xmlPath, String text, Map<String, String> attributes) {
        Element element = (Element) this.document.selectSingleNode(xmlPath);
        element.setText(text);
        if (attributes != null) {
            Set<String> set = attributes.keySet();
            for (String key : set) {
                element.addAttribute(key, attributes.get(key));
            }
        }
    }
     
    /**
     * 删除节点
     * @param xPath 选择器
     */
    public void deleteElement(String xPath) {
        Element element = (Element) this.document.selectSingleNode(xPath);
        if (element != null)
            element.getParent().remove(element);// 删除只能父元素删除子元素
    }
     
    /**
     * 删除节点,命名空间
     * @param xxPath 选择器
     */
    public void deleteElementWithNameSpance(String xxPath) {
        Map<String, String> namespances = new HashMap<String, String>();
        String defaultNamespace = this.document.getRootElement().getNamespaceURI();
        namespances.put("default", defaultNamespace);
        XPath xPath = this.document.createXPath(xxPath);
        xPath.setNamespaceURIs(namespances);
        Element element = (Element) xPath.selectSingleNode(this.document);
        if (element != null)
            element.getParent().remove(element);// 删除只能父元素删除子元素
    }
 
    /**
     * 删除节点
     * @param xxPath 选择器
     * @param index 指定节点
     */
    public void deleteElement(String xxPath, Integer index) {
        Element element = (Element) this.document.selectSingleNode(xxPath + "[" + index + "]");
        if (element != null)
            element.getParent().remove(element);// 删除只能父元素删除子元素
    }
 
    /**
     * 删除所有节点
     * @param xxPath 选择器
     */
    public void deleteAllElement(String xxPath) {
        Element element = (Element) this.document.selectSingleNode(xxPath);
        while (element != null) {
            element.getParent().remove(element);// 删除只能父元素删除子元素
            element = (Element) this.document.selectSingleNode(xxPath);
        }
    }
 
    /**
     * 删除属性
     * @param xxPath 选择器
     * @param attribute 属性名称
     * @param value 属性的值
     */
    public void deleteAttribute(String xxPath, String attribute, String value) {
        Element element = (Element) this.document.selectSingleNode(xxPath + "[@" + attribute + "=\"" + value + "\"]");
        while (element != null) {
            element.remove(element.attribute(attribute));
            element = (Element) this.document.selectSingleNode(xxPath + "[@" + attribute + "=\"" + value + "\"]");
        }
    }
 
    /**
     * 写出文件
     */
    public void write() {
        XMLWriter writer = null;
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("utf-8");// 设置XML文件的编码格式
            writer = new XMLWriter(new FileOutputStream(this.path), format);
            writer.write(this.document);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                writer = null;
                e.printStackTrace();
            }
        }
    }
     
}