XML添加节点换行和缩进问题

问题

当我们向XML文件中新增节点时,可能会遇到新增节点写在了一行,或者分行后没有缩进。这样会影响XML文件的美观,以及我们可阅读性。

今天我们用DOM解决以上问题,假设有一个XML文件:Book.xml,以下就是我们要达到的效果。

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="1">
        <name>C++ primer plus</name>
        <price>80</price>
    </book>
</books>

DOM中换行与缩进问题的解决方法

操作步骤

1.首先创建工厂,得到DocumentBuilder对象

DocumentBuilder builder=DocumentBuilderFactory.newInstance().newDocmentBuilder();

2.如果XML文件存在,就得到XML文件中的根节点,如果不存在创建一个根节点。

存在

Document document=builder.parse(file);//得到文档对象

Element root=document.getDocumentElement();//得到根节点

不存在

Document document=builder.newDocument();//创建文档对象

Element root=document.createElement("books");//创建一个根节点  books 根节点名

3.创建子节点,并赋值

Element book=document.createElement("book");//创建book节点

book.setAttribute("id","1");//为book节点设置属性名 和属性值

Element name=document.createElement("name");

name.setTextContent("C++ Primer plus");//设置节点间的文本值

Element price=documenr.createElement("price");

price.setTextContent("80");

4.添加节点到对应的位置

book.appendChild(name);

book.appendChild(price);//将name price作为book的子节点

root.appendChild(book);//将book节点添加到根节点

PS:注意添加的顺序。如果文件不存在 就将root节点添加到document中,如果存在则不需要。

document.appendChild(root);

5.将创建及添加好的元素写入到xml文件中,用方法将其封装

public static void writer(Document document,String path){

        OutputFormat format=new OutputFormat(document);//输出格式

        format.setIndent(2);//设置输出格式  缩进2个单位

        fomat.setIndenting(true);//设置缩进

        XMLSerializer serializer=new XMLSerializer(new FileWriter(path),format);//写入的位置 以及写入的格式

        serializer.serialize(document);//写入Document对象

}

PS:OutputFormat和XMLSerializer导入的包是com.sun.org.apache.xml.internal.serialize下面的包。

具体实现

package Demo;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo {
    public static void main(String[] args) throws Exception {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        boolean fig=false;//用于标记文件是否存在  false表示不存在
        Document books=null;
        Element root =null;
        String path="Books.xml";//文件路径
        File file=new File(path);
        if(!file.exists()){//文件不存在
            file.createNewFile();//新建一个文件
            books=builder.newDocument();//新建一个文档对象
            //创建根节点
            root=books.createElement("books");
        }else {//文件存在
            fig=true;
            books = builder.parse(path);//获得文件的文档对象
            //得到根节点
            root=books.getDocumentElement();
        }
        //创建节点设置属性
        Element book = books.createElement("book");
        book.setAttribute("id","1");

        Element price = books.createElement("price");
        price.setTextContent("80");
        Element name = books.createElement("name");
        name.setTextContent("C++ primer plus");

        //添加节点
        book.appendChild(name);
        book.appendChild(price);

        root.appendChild(book);
        //如果文件存在    不需要添加根节点(一个XML中只能有一个根节点)   
        if(!fig)    books.appendChild(root); //不存在将创建的根节点添加进去
        writer(books,path);//写入XML文件
    }
    public static void writer(Document document,String path) throws IOException {
        OutputFormat format= new OutputFormat(document);//写入格式
        format.setIndent(2);//缩进两个单位
        format.setIndenting(true);//开启缩进
        XMLSerializer serializer=new XMLSerializer(new FileWriter(path),format);//写入的位置 以及格式
        serializer.serialize(document);
    }
}

结果:


换行和缩进都有了,达到了我们想要的效果。

总结

或许有小伙伴会问,在新增节点时,为何每次都需要判断文件是否存在?当我们需要频繁对XML文件进行操作时,只需将创建节点那部分封装即可。首先,如果文件不存的话,我们就需要创建一个XML文件,并且创建一个根节点。如果文件存在的话,我们只需得到根节点。然后将后面创建的节点加入到根节点下即可。需要注意的是如果文件不存在,还需要将根节点添加到文档(Document)对象下。


        每日鸡汤:该发生的总会发生,大多数担心的事又多数不会发生!

Over!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值