XML文档操作之JAXP下实现

JAXP是java API for xml PRocessing的缩写。
其API可以在javax.xml.parsers 这个包中找到。这个包向用户提供了两个最重要的工厂类,SAXParserFactory 和DocumentBuilderFactory,我们可以通过这两个类实现之后对XML文件的操作。作为一个xml的解析器,w3c组织官方推荐使用Dom(Document Object Model 文档对象模型)方式进行解析,但是实际上的社区标准是SAX(Simple API For XML)。两者各有各的好处,下面是简易的两点区别:

  • dom方式可以实现对XML文档的CRUD(即增删改查操作)
  • sax主要是能够快速的查找某一个节点的值(注意不能CRUD)


今天我们就一起来看一看Dom方式来解析XML吧。

原理

DOM是一个以“面向对象”思路进行操作的方式,所谓对象就是指Dom实际上是将一个xml文件一下子装载到JVM中,然后根据XML文件的格式和内容在JAXP中创建一个“对象树”模型的方式,然后只需要针对这些对象进行操作就可以实现对XML文档的操作。



怎样得到一个对象模型:

  • 利用DocumentBuilderFactory创建一个解析工厂实例(工厂)
  • 得到一个DocumentBuilder解析器(机器)
  • 然后通过对机器装载xml文件得到一个解析对象Document的实例
  • 对这个Document进行一些列的操作即可
private static Document getDocument(String filePath) {
        // TODO Auto-generated method stub
        //get the prase factory
                DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
                //get the prase machine
                DocumentBuilder builder;
                Document document = null;
                try {
                    builder = factory.newDocumentBuilder();
                    //get the Object of the xml.file
                    document = builder.parse(filePath);
                } catch (ParserConfigurationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (SAXException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            return document;
    }


完成了对xml文档的操作之后,这就完了吗?思考发现并没有完成,因为我们操作的文档上之前一下子加载到内存中的文件,我们改变的仍旧只是内存中的文件,要想对原文件进行彻底的修改,我们还得有一些写回的操作,这就需要用到TransformerFactory类和Transformer类。

  • 使用TransformerFactory工厂类得到一个工厂
  • 通过工厂“加工”出来一个Transformer类
  • 调用Transformer的transform方法就可以完成写回的操作了。
    但是通过查询API文档,发现transform方法的参数需要进行一些包装。
    所以还需要下面的包装方法。
public static  void WriteBack(Document document,String path){
        TransformerFactory factory= TransformerFactory.newInstance();
        try {
            Transformer transformer= (Transformer) factory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result= new StreamResult(new File("src/Person.xml"));
            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


剩下的操作就是比较简单的了,代码中注释也比较详尽,就不在过多的描述。



小结:

好处:全面,操控范围广

缺点:文件一下子装载到内存中,有可能导致内存泄漏(1、虽然Windows下有虚拟内存解决方案;2、我们也可以手动的更改Java虚拟机中-Xxm (大小)方式更改运行时内存;但最好是对文件较小的时候采用这个方式)



下面是我的项目中src目录下的一个Person.xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Persons>
    <Person>
        <Name>Summer</Name>
        <Age>20</Age>
        <Address>ShangHai</Address>
    </Person>

    <Person>
        <Name>GRB</Name>
        <Age>10</Age>
        <Address>DaLian</Address>
    </Person>
</Persons>


下面是对这个XML文档的CRUD操作:

package com.summer.jaxp;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class PraseXMLByJAXP {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //set the xml file path
        String filePath="src/Person.xml";
        //get the operation object ----document
        Document document= getDocument(filePath);

        //get the xml file result
        getTheResult(document);

        //update the xml file
        upDateTheXMLFile(document);

        //add one Node
        addOneNode(document,filePath);

        //delete one node
        deleteOneNode(document , filePath , "Address");

        //operate the attribute
        operateTheAttribute(document,filePath);

    }

    private static void operateTheAttribute(Document document, String filePath) {
        // TODO Auto-generated method stub
        Element person = (Element) document.getElementsByTagName("Person").item(1);
        //add some attribute
        person.setAttribute("sex", "Man");
        person.setAttribute("married", "Yes");

        //update one special attribute
        person.setAttribute("sex", "Woman");

        //delete one special attribute
        person.removeAttribute("sex");

        //remember to write the operation result back to xml file, or that's only be saved in memary
        WriteBack(document, filePath);
    }

    private static void deleteOneNode(Document document, String filePath,
            String TagName) {
        //you must get the node's parent then operate its's father to remove this node
        Node oldChild = document.getElementsByTagName(TagName).item(1);
        oldChild.getParentNode().removeChild(oldChild);
        WriteBack(document, filePath);

    }

    private static void addOneNode(Document document,String filePath) {
        // TODO Auto-generated method stub
        Node parent =  document.getElementsByTagName("Person").item(1);
        Node child= document.createElement("Hobby");
        child.setTextContent("Basketball and Coding!");
        parent.appendChild(child);
        WriteBack(document, filePath);
    }

    private static Document getDocument(String filePath) {
        // TODO Auto-generated method stub
        //get the prase factory
                DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
                //get the prase machine
                DocumentBuilder builder;
                Document document = null;
                try {
                    builder = factory.newDocumentBuilder();
                    //get the Object of the xml.file
                    document = builder.parse(filePath);
                } catch (ParserConfigurationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (SAXException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            return document;
    }

    /**
     * write the operation result back to xml file
     * @param document
     * @param path
     */
    @Test
    public static  void WriteBack(Document document,String path){
        TransformerFactory factory= TransformerFactory.newInstance();
        try {
            Transformer transformer= (Transformer) factory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result= new StreamResult(new File("src/Person.xml"));
            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static void upDateTheXMLFile(Document document) {
        // TODO Auto-generated method stub
        NodeList list=document.getElementsByTagName("Name");
        for(int i=1;i<list.getLength();i++){
            Node node= list.item(i);
            node.setTextContent("GRB");
        }
        WriteBack(document, "src/Person.xml");

    }

    private static void getTheResult(Document document) {
        // TODO Auto-generated method stub
        NodeList list=document.getElementsByTagName("Name");
        for(int i=0;i<list.getLength();i++){
            System.out.println(list.item(i).getTextContent());
        }
    }

}


代码运行后的Person.xml有很多已经改变,下面是总的操作的结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Persons>
    <Person>
        <Name>Summer</Name>
        <Age>20</Age>
        <Address>ShangHai</Address>
    </Person>

    <Person married="Yes">
        <Name>GRB</Name>
        <Age>10</Age>

        <Hobby>Basketball and Coding!</Hobby>
    </Person>
</Persons>


分析:
细心地朋友会发现:

  • 第二个Person节点的属性多了一个
  • 第二个Person节点的子节点address少了一个
  • 第二个Person节点多了一个子节点hobby
    这便是对XML文档操作的最好的体现。


总结:
使用解析器对xml的解析虽然方式众多,但是在实际中不同的情况选取合适的方式能大大减少不必要的麻烦。所以我们要谨慎的考虑到底要使用那种方式。

时间: 2024-10-27 07:21:58

XML文档操作之JAXP下实现的相关文章

Prototype Ajax读取XML文档实现联动下拉框实例

在使用PHP进行WEB2.0网站开发时,时常需要用到Ajax技术来增加用户体验,当前比较流行的Ajax开发框架有Prototype,Jquery,Lightbox等,今天和大家分享如何利用Prototype和XML文档进行交互以实现Ajax联动下拉菜单的例子. Ajax(Asynchronous JavaScript and XML)使用XHTML和CSS标准化呈现,使用DOM实现动态显示和交互,使用XML和XSTL进行数据交换与处理,使用XMLHttpRequest对象进行异步数据读取,使用J

简述PHP4和PHP5版本下解析XML文档的操作方法

在PHP网站开发与建设过程中,时常会碰到需要对XML文档进行解析,PHP4版本自带了XML解析器(sax),PHP5版本增加了SimpleXML(基于dom)的XML扩展,对XML的解析更是非常方便,今天和大家分享下在不同环境下对XML文档进行解析的方法.XML文档 1234567891011121314151617181920 <?xml version="1.0" encoding="gbk"?> <LeapsoulXML>      

DOM文档操作和XML文件互相转换的java实现 (转贴)

dom|xml|转换 DOM文档操作和XML文件互相转换的java实现 [ 作者: 郭洪锋   添加时间: 2001-10-19 8:16:09 ] 郭洪锋 (ghf_email@sohu.com) 简介:该文简要描述了DOM的概念和内部逻辑结构,给出了DOM文档操作和XML文件互相转换的java实现过程.1. DOM简介 目前,W3C已于2000年11月13日推出了规范DOM level 2.文档对象模型(DOM)是HTML和XML文档的编程接口规范,它与平台和语言是无关的,因而可以用各种语言

[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档

[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档 楼主  发表于 2013-5-21 22:00:51 | 查看: 475| 回复: 0 使用DOM创建和操作XML文档 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 在上一节中我们用手写的方法建立了一个XML文档,并且用DOM的方法对其进行了读取.现在我们使用代码来创建那个XML文档,并且对它实现查找.更新.插入等操作. 环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2

php中操作xml文档程序代码

 代码如下 复制代码   /* <?xml version="1.0" encoding="UTF-8"?> <班级> <学生 number="101"> <名字>孙悟空</名字> <名字>孙行者</名字> <年龄>猴精猴精</年龄> <介绍></介绍> </学生> <学生 number="

创建可编辑的xml文档(之三)执行拖放操作

xml|创建|执行 执行托放操作 定义了treeview 显示得内容以后,现在你应该准备处理如何四处移动元素了,大多数得开发人员在处理拖放操作时得通用观念都是很相似得,无论使用visual c++ visual basic 或者任何一种.net 语言,所以我一直用下面的四个方法处理这个操作: MouseDown-----用户选择得内容 DragEnter---用户开始拖动选中得项目 DragOver ---用户拖动选中得项目经过另一个项目 DragDrop---用户在某个地方放下选择得项目 执行

创建可编辑的xml文档(之四) 删除、改名、插入操作

xml|插入|创建 执行删除.改名.插入操作   实现了拖放操作就已经完了最难的部分,但是出于完整性考虑,还应该提供一些更好的基本的编辑功能. 下面仅仅用四行代码就可以实现删除操作:   重命名操作需要更多的一些考虑,你可以调用   最后一个挑战就是如何按照需求创建一个新的文件夹.         insert_fragment.DocumentElement treeview 控件可以缓存一个结构的副本,将它作为一个临时变量来创建一个新的文件夹集合.你所要做的仅仅是确保被定义得文件夹可以被  

Java实现DOM文档操作和XML文件互相转换

dom|xml|转换 本文简要描述了DOM的概念和内部逻辑结构,实例讲述DOM文档操作和XML文件互相转换的java实现过程. 1. DOM简介 目前,W3C已于2000年11月13日推出了规范DOM level 2.文档对象模型(DOM)是HTML和XML文档的编程接口规范,它与平台和语言是无关的,因而可以用各种语言在各种平台上实现.该模型定义了THML和XML文件在内存中的逻辑结构(即为文档),提供了访问.存取THML和XML文件的方法.利用DOM规范,可以实现DOM 文档和XML之间的相互

操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP)

原文:操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP) 不管是用 PHP 还是 C#, 在操作 XML 的时候我们除了一个节点一个节点去取值之外, 还有一个非常方便的表达式, 就是 XPATH    而昨晚在使用 XPATH 的时候, 遇到一个问题, 改了一个晚上才搞定, 差点没吐血. 果然基础知识要掌握扎实啊!! 假设有以下一份 XML 文档:     我们要获取所有歌曲的标题, 一般是使用以下的 XPATH 表达式: 代码如下: /playlist/trackList/tr