问题
当我们向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!