Android之DOM生成XML文件

Android之DOM生成XML文件

文章链接

知识点

  1. Document获取和设置文档属性;
  2. 创建节点并设置属性;
  3. 创建节点并且设置value;
  4. 转换生成XML;
  5. 新名词记录{Document:DOM的XML文档holder类;工厂模式;transformer:DOM实际转换生成XML类;}

概述

上一篇文章,讲解了如何利用SAX生成XML文件。
Android之pull生成XML及XmlSerializer详解
Android之SAX生成XML及TransformerHandler解析
下面来看一下如何使用DOM来生成XML文件。

DOM解析和生成XML都是利用树状结构来进行解析和生成,这是一个相反的过程。如果你了解了DOM的解析,那么理解生成也不是问题了。


XML文档Document

我们知道DOM是先将整个文档读入内存解析,就需要获取它的document对象,然后再根据整个文档的树结构,依次由“树根”–>“树梢”进行依次读取解析。同理,在生成XML的时候,也需要同样获取到“树根”,然后依次创建节点,加入到对应的位置,具体代码如下。

//工厂模式管理documentbuilder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//documentbuilder用于管理解析或者生产XML
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();

由上面可以看到,DOM的实例管理和SAX/PULL是一样的,都是用了工厂模式,你要document对象可以,我给你创建。但是因为document对象是被DocumentBuilder管理,所以创建一个documentbuilder给你,documentbuilder的功能是解析或者生成XML,并且将结果放入到document对象中返回。而document对象则是对XML的树状结构进行保存和获取节点和节点数据等的操作,当然也具有创建节点的功能。

获取到document对象就可以进操作了。

创建XML文档说明

首先当然是对文档进行说明的一些设置了,例如版本,编码方式和命名空间等等。DOM比较好的就是都直接有对应的设置方法,不用获取到key然后再进行设置对应的值。
方法如下:

document.setPrefix();
document.setDocumentURI();
document.setXmlVersion();
document.setXmlStandalone();
//···
创建节点并设置属性

创建节点(元素)的方法比较都是相同的,需要传入节点的名称,不同的是要手动加入到需要节点并设置属性,代码如下所示:

//创建节点user
Element userElement = document.createElement("user");
//设置此节点id属性,结果为<user id = "1">
userElement.setAttribute("id", String.valueOf(userBean.getId()));
创建节点并且设置value

创建了节点和属性,接下来创建节点,并且添加节点下对应的数值,例如创建userName对象,并设置yaojt的值(< userName>yaojt),对应代码如下:

//创建userName节点
Element userNameElement = document.createElement("userName");
//给userName节点加入value "yaojt"
userNameElement.appendChild(document.createTextNode("yaojt");
//将userName的节点加入到user节点,作为user节点的子节点
userElement.appendChild(userNameElement);

上面的代码已经说清楚了,主要createTextNode()方法生成value,并且调用该(userName节点)节点的appendChild()方法加入到此节点下,作为此节点的value。该节点有从属于哪一个父节点(user节点),那么调用相对应的父节点的appendChild()加入子节点。

生成XML

上面的步骤中,我们利用document建立好了XML的层次结构,那只是在document对象里的,并没有进行实际的转换,并且进行输出。API提供了Transformer类进行转换的操作。而此类又是由工厂模式进行管理的。获取的方法如下:

//转换工厂类
TransformerFactory transformerFactory = TransformerFactory.newInstance();
//实际转换类
Transformer transformer = transformerFactory.newTransformer();
//设置输出文档属性说明
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

在转换类中,调用transform(Source xmlSource, Result outputTarget)方法就可以进行实际的转换操作了。我们看到需要两个参数,

参数1是输入需要转换的XML,Source类的作用是包含XML数据源的对象,实际上对于DOM,需要使用其子类DOMSource进行操作,DOMSource有3个构造方法,对于无参和1个参数构造方法,都是一样要设置Node对象(document类也是继承node类),2个参数的构造方法,第二个参数传入node相关联的base URI。

参数2是结果接收的Result对象。Result是一个接口类,实际中使用的是子类StreamResult,StreamResult也是一个间接管理输出的类,可以设置输出流,writer和文件等输出方式。这里利用了Writer接口类进行输出结果,实际使用的是PrintWriter子类,传入一个OutputStream对象,输出为本地的XML文件。

也可以使用StringWriter对象作为结果输出接受者。

具体的代码如下:

DOMSource domSource = new DOMSource(document);
PrintWriter printWriter = new PrintWriter(outputStream);
StreamResult streamResult = new StreamResult(printWriter);
transformer.transform(domSource, streamResult);

其实每一步都是遵循上面的步骤,只要按着结构,依次设置节点层次,整个文档就OK了。

最后给出全部的代码,如下:

/**
     * DOM生成XML
     *
     * @param userBeanList 实体类集合
     * @param outputStream 输出流
     */
    public static void buildXmlByDom(List<UserBean> userBeanList, OutputStream outputStream) {
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.newDocument();
            //创建根元素<users>
            Element usersElement = document.createElement("users");
            document.appendChild(usersElement);

            for (UserBean userBean : userBeanList) {
                //创建二级元素<user>
                Element userElement = document.createElement("user");
                //设置节点的属性<user id="1">的id属性,如有多个属性,则依次增加
                userElement.setAttribute("id", String.valueOf(userBean.getId()));

                Element userNameElement = document.createElement("userName");
                userNameElement.appendChild(document.createTextNode(userBean.getUserName()));
                userElement.appendChild(userNameElement);

                Element passwordElement = document.createElement("password");
                passwordElement.appendChild(document.createTextNode(userBean.getPassword()));
                userElement.appendChild(passwordElement);

                Element ageElement = document.createElement("age");
                ageElement.appendChild(document.createTextNode(String.valueOf(userBean.getAge())));
                userElement.appendChild(ageElement);

                usersElement.appendChild(userElement);
            }

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            DOMSource domSource = new DOMSource(document);
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            PrintWriter printWriter = new PrintWriter(outputStream);
            StreamResult streamResult = new StreamResult(printWriter);
            transformer.transform(domSource, streamResult);
        } catch (ParserConfigurationException | TransformerException e) {
            e.printStackTrace();
        }
    }

实体类

private int id;
    private String userName;
    private String password;
    private int age;
    //setter和getter方法

调用上面的方法运行测试。

List<UserBean> userBeanList = XmlUtil.parseXmlByPull(inputStream);
try {
            String outPutPath = file.getAbsolutePath() + "buildusersbydom.xml";
            File outFile = new File(outPutPath);
            if (outFile.exists()){
                outFile.delete();
            }
            outFile.createNewFile();
            CommonLog.logInfo("path:" + outFile.getAbsolutePath());
            FileOutputStream fileOutputStream = new FileOutputStream(outFile);
            XmlUtil.buildXmlByDom(userBeanList, fileOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

关于parseXmlByPull()方法,请看这里的文章

本例子是将生产的XML文件放在本地buildusersbydom.xml文件夹中了。下面给出一个输出的XML截图。

image description


总结

利用DOM生成XML文档,首先需要创建一个完整的document树结构,比如根节点和子节点以及节点间的层次关系,依次appendChild()到对应的层级中。然后需要调用转换器Transformer,并且设置输出结果接受对象Source,一个DOM生成的XML文件就OK了。

以上就是所有内容,如有任何问题,请及时与我联系,谢谢!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值