使用Java处理XML文件

XML 是一种可扩展标记语言,它和 HTML 的区别就在于: HTML 中的标记是固定的,然后每个标记都会代表某些特殊含义,而 XML 中的标记却不是固定的,可以自己定义元素,所以它就不会像 HTML 那样每个元素都会有一个通用的含义,而 XML 中的元素因为是每个使用者自己根据需求定义的,因此每种元素的含义当然是自己最清楚了,不过 XML 文档的元素都会取见名知意的,因此阅读性也会有保证。

1.导入jar包

我们解析 XML 文件是使用 Dom4j 来进行的,这是第三方开源组织提供的开发包,因此必须先导入 jar 包才能使用,首先在项目根目录下新建一个 lib 文件夹,然后将 Dom4jjar 包拷贝到里面,我使用的是 dom4j-1.6.1.jar ,其实只要在网上搜索都可以在官网下载到的,将 jar 包拷贝到 lib 文件夹之后,然后在该文件夹中选中这个 jar 包,单击右键选择 Build Path , 然后再选择 Add to Build Path ,这样就成功了。

2.解析方式

解析 XML 文件有两种方式,分别是: DOM 解析和 SAX 解析, DOM 解析在解析的时候是一次性加载所有 XML 标签元素,因此能够快速地查找和操作标签元素,但是因为是一次性加载,所以如果加载的文档过大的话,就有可能导致内存溢出;而 SAX 解析在解析的时候是一个节点一个节点进行解析,因此不管文档多大都可以都可以进行解析,但是就不能快速方便地操作所有的节点和属性了。

解析方式:
    DOM解析:一次性加载,查找和操作速度快,但文件过大时内存有可能溢出
    SAX解析:一个节点一个节点进行解析,速度不是很快

3.解析文件

3.1 读入文档和写出文档

想要对 XML 文件进行解析,必须先使用程序将文档读入到内存当中,这样才能对节点和节点属性进行增删改查操作,当操作完成之后,要保存操作,当然就要将文档对象写回到文件当中。

读入文档:

public static Document getDocument() throws DocumentException{
    SAXReader reader = new SAXReader();
    Document document = reader.read("src/day14/hero.xml");
    return document;
}

写出文档:

public static void write2Xml(Document document) throws IOException {
    XMLWriter writer = new XMLWriter(new FileWriter("src/day14/hero.xml"));
    OutputFormat format = OutputFormat.createPrettyPrint();
    //设置字符编码
    format.setEncoding("UTF-8");
    writer = new XMLWriter(new FileOutputStream(new File("src/day14/hero.xml")), format);
    writer.write(document);
}

3.2 操作元素的方法

获取文档对象中的根元素

Element getRootElement()

Element rootElement = document.getRootElement();

操作子元素的方法
获取元素:

List elements() :返回调用该方法元素中所有子元素的集合
List elements(String name):根据指定的元素名称来获取调用该方法元素的所有的子元素
Element element(String name):根据指定名称来获取调用该方法元素的子元素对象,如果有多个子元素都是指定的名称,则返回第一个子元素

删除元素:
删除元素是无法自己删除自己的,只能靠父元素来删除自己。

Element parentElement = theElement.getParent();
parentElement.remove(theElement); 

添加元素:

Element cityElement = rootElement.addElement("City");
cityElement.setText("南阳");

3.3 操作元素文本的方法

String  elementText(String name) :根据指定的子元素名称,来获取子元素中的文本
String  getText() :获取当前元素对象的文本
void setText(String text):设置当前元素对象的文本

3.4 操作元素属性的方法

String  attributeValue(String name):根据指定的属性名称获取其对应的值
public Element addAttribute(String name,String value):根据指定的属性名称和值进行添加或者修改

4.自己写的小例子

因为程序的注释写的还算清晰,所以直接把代码放在下面了

操作的 XML 文件(hreo.xml):

<?xml version="1.0" encoding="UTF-8"?>
<lol company="tencent"> 
  <hero> 
    <name>盖伦</name>  
    <dps>80</dps> 
  </hero>  
  <hero> 
    <name>张飞</name>  
    <height>190</height>  
    <age>19</age> 
  </hero>  
  <hero> 
    <name>嘉文</name>  
    <dps>85</dps> 
  </hero> 
</lol>

Dom4jUtils类:

public class Dom4jUtils {

    public Dom4jUtils() {

    }

    public static Document getDocument() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(new File("src/day14/practice/hero.xml"));
        return document;
    }

    public static void write2Xml(Document document) throws IOException {
        XMLWriter writer = new XMLWriter(new FileWriter("src/day14/practice/hero.xml"));
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        writer = new XMLWriter(new FileOutputStream(new File("src/day14/practice/hero.xml")), format);
        writer.write(document);
    }
}

Dom4jDemo类:

public class Dom4jDemo {
    public static void main(String[] args) throws DocumentException,
            IOException {
        getAttribute();
    }

    public static void getAttribute() throws DocumentException, IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取到根元素
        Element rootElement = document.getRootElement();
        // 获取根元素中的属性
        String companyName = rootElement.attributeValue("company");
        System.out.println("companyName:" + companyName);
        // 将文件对象重新写入到文件中
        Dom4jUtils.write2Xml(document);
    }

    public static void addAttribute() throws DocumentException, IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取到根元素
        Element rootElement = document.getRootElement();
        // 为根元素添加属性
        rootElement.addAttribute("company", "tencent");
        // 将文件对象重新写入到文件中
        Dom4jUtils.write2Xml(document);
    }

    public static void addElementWithLocation() throws DocumentException,
            IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取根元素
        Element rootElement = document.getRootElement();
        // 获取根元素里面的子元素集合
        List<Element> elements = rootElement.elements();
        // 获取子元素集合中第二个元素
        Element secondElement = elements.get(1);
        // 创建一个新元素
        Element heightElement = DocumentHelper.createElement("height");
        // 设置元素中的文本
        heightElement.setText("190");

        List<Element> elements2 = secondElement.elements();
        elements2.add(1, heightElement);
        // 将文件对象重新写入文件
        Dom4jUtils.write2Xml(document);
    }

    public static void addElement() throws DocumentException, IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取根元素
        Element rootElement = document.getRootElement();
        // 获取根元素里面的子元素集合
        List<Element> elements = rootElement.elements();
        // 获取子元素集合中第二个元素
        Element secondElement = elements.get(1);
        // //创建一个新元素
        // Element ageElement = DocumentHelper.createElement("age");
        // //设置元素中的文本
        // ageElement.setText("19");
        // //添加到指定元素中
        // secondElement.add(ageElement);
        Element ageEleElement = secondElement.addElement("age");
        ageEleElement.setText("17");
        // 将文件对象重新写入文件
        Dom4jUtils.write2Xml(document);
    }

    public static void removeNode() throws DocumentException, IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取根元素
        Element rootElement = document.getRootElement();
        // 获取根元素里面子元素的集合
        List<Element> elements = rootElement.elements();
        // 获取集合之中的第二个元素
        Element secondElement = elements.get(1);
        // 获取这个元素之中的dps元素
        Element dpsElement = secondElement.element("dps");
        // 删除这个元素
        secondElement.remove(dpsElement);
        // 将文件对象重新写入文件
        Dom4jUtils.write2Xml(document);
    }

    public static void changeText() throws DocumentException, IOException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取根元素
        Element rootElement = document.getRootElement();
        // 获取根元素下面的子元素集合
        List<Element> elements = rootElement.elements();
        // 获取子集合里面的第二个元素
        Element secondeElement = elements.get(1);
        // 获取其中的name元素
        Element nameElement = secondeElement.element("name");
        // 修改这个元素的文本值
        nameElement.setText("张飞");
        // 重新将文本对象写入到xml文件当中
        Dom4jUtils.write2Xml(document);
    }

    public static void getAllNodes() throws DocumentException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取文件根元素
        Element rootElement = document.getRootElement();
        // 循环遍历根元素
        rootWalk(rootElement);
    }

    public static void rootWalk(Element element) {
        // 获取元素名称
        String name = element.getName();
        System.out.println(name);
        // 得到元素的子元素集合
        List<Element> elements = element.elements();
        // 遍历集合,并在循环中对每个子元素进行迭代
        for (int i = 0; i < elements.size(); i++) {
            Element e = elements.get(i);
            rootWalk(e);
        }
    }

    public static void getElement() throws DocumentException {
        // 获取xml文件对象
        Document document = Dom4jUtils.getDocument();
        // 获取根元素
        Element rootElement = document.getRootElement();
        // 获取根元素里面的子元素集合
        List<Element> elements = rootElement.elements();
        // 获取子元素集合中的第2个元素
        Element secondElement = elements.get(1);
        // 获取这个元素的节点名称
        System.out.println("name:" + secondElement.getName());
        // 获取这个节点之下的name子节点
        Element nameElement = secondElement.element("name");
        // 获取name子节点中的文本
        System.out.println(nameElement.getText());
        // 获取这个节点之下的dps子节点
        Element dpsElement = secondElement.element("dps");
        // 获取dps子节点中的文本
        System.out.println(dpsElement.getText());
    }
}

5.总结

其实自己现在对于 Dom4j 解析 XML 文件还没有使用的那么熟练,有很多东西都还要查 API 和资料,只能说对一些基础有了一点了解吧,需要使用更深入的东西的时候再回来查吧。感觉现在最重要的是知道如何解析 XML 文件,知道如何获取 XML 中存储的信息,如果有需要当然也要进行修改,就是要把这些基本操作把握稳固吧。个人感觉比较重要的一点就是在使用过程中有不清楚的地方就果断查 API 吧。

坚持原创技术分享,您的支持将鼓励我继续创作!