版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luo4105/article/details/74518205
该系列代码都在https://code.csdn.net/luo4105/study_http项目的com.lc.xml包中
Xml读取解析有两种方式,dom和sax。SAX可以快速扫描一个大型的XML文档,当它找到查询标准时就会立即停止,然后再处理之。DOM是把XML全部加载到内存中建立一棵树之后再进行处理。所以DOM不适合处理大型的XML【会产生内存的急剧膨胀】。
dom和sax区别
dom解析是直接把xml一个parse操作,转成了document对象,简单粗暴,不过这样会耗费很多内存的资源。所以,在临床上我们一般只用来读一些配置文件或者比较小的xml文件
sax解析则是一个节点一个节点得往下读,读到后面的,前面的也就释放掉了,所以不会存在说耗费大量内存一说。所以对大型的xml文件用sax解析就再好不过了。
Marshaller和Unmarshaller可以直接实现javabean和xml的相互转换,强大、简单、使用。
Java常用的解析技术有两种, dom4j、Marshaller和Unmarshaller。Marshaller和Unmarshaller是jdk自带的,不需要引入jar包。Marshaller和Unmarshaller可以方便实现xml与javabean之间的转换,适合于xml格式固定的解析。dom4j适合xml结构不不统一、需要自定义的xml解析。
dom4j需要添加dom4j.jar包,这里通过写和读的例子来讲解dom4j。
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
解析xml的过程是通过创建Document对象,然后根据Document对象操作xml,所以初始化Document是第一步、下面是最常用的三种初始化创建方式。
(1) 手动创建Document对象
Document document = DocumentHelper.createDocument();
(2) 加载xml文件创建Document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/main/resources/blog-data.xml"));
(3) 通过xml内容字符串创建Document对象
String xmlStr = "<students>......</students>";
Document document = DocumentHelper.parseText(xmlStr);
Element是xml中节点对象,Element常见操作有
1.添加节点
.addElement("");
2.设置数据
. addText("");
3.添加属性
.addAttribute("","");
下面是一个java创建Document对象并输出到xml文件的程序。
@Test
public void xmlWriteByNIO() throws Exception {
Document document = DocumentHelper.createDocument();
Element root = document.addElement("bloginfos");
root.addAttribute("id", "12");
Element info = root.addElement("bloginfo");
Element name = info.addElement("name");
name.addText("NIO系列(六)——pipe");
Element url = info.addElement("url");
url.addText("http://blog.csdn.net/luo4105/article/details/73650562");
System.out.println(document.asXML());
RandomAccessFile aFile = new RandomAccessFile("src/main/resources/blog-data.xml", "rw");
FileChannel inChannel = aFile.getChannel();
byte[] picbytes = document.asXML().getBytes("UTF-8");
ByteBuffer xmlDataBuf = ByteBuffer.wrap(picbytes);
while (xmlDataBuf.hasRemaining()){
inChannel.write(xmlDataBuf);
}
}
打开xml
<?xml version="1.0" encoding="UTF-8"?>
<bloginfos id="12"><bloginfo><name>NIO系列(六)——pipe</name><url>http://blog.csdn.net/luo4105/article/details/73650562</url></bloginfo></bloginfos>
可以使用OutputFormat对xml进行格式化输出,例子经过格式化修改如下
@Test
public void xmlWrite() throws Exception {
Document document = DocumentHelper.createDocument();
Element root = document.addElement("bloginfos");
root.addAttribute("id", "12");
Element info = root.addElement("bloginfo");
Element name = info.addElement("name");
name.addText("NIO系列(六)——pipe");
Element url = info.addElement("url");
url.addText("http://blog.csdn.net/luo4105/article/details/73650562");
StringWriter writer = new StringWriter();
OutputFormat format = OutputFormat.createPrettyPrint();
format.setNewlines(true);
// 生成缩进
format.setIndent(true);
// 使用4个空格进行缩进, 可以兼容文本编辑器
format.setIndent(" ");
format.setEncoding("UTF-8");
XMLWriter xmlwriter = new XMLWriter(writer, format);
xmlwriter.write(document);
System.out.println(writer.toString());
RandomAccessFile aFile = new RandomAccessFile("src/main/resources/blog-data.xml", "rw");
FileChannel inChannel = aFile.getChannel();
inChannel.truncate(0);
byte[] picbytes = writer.toString().getBytes("UTF-8");
ByteBuffer xmlDataBuf = ByteBuffer.wrap(picbytes);
while (xmlDataBuf.hasRemaining()){
inChannel.write(xmlDataBuf);
}
}
输出结果
<?xml version="1.0" encoding="UTF-8"?>
<bloginfos id="12">
<bloginfo>
<name>NIO系列(六)——pipe</name>
<url>http://blog.csdn.net/luo4105/article/details/73650562</url>
</bloginfo>
</bloginfos>
同样是通过Element来读取数据,常用的方法有
1.获得子节点
.elements();
2.获得节点名
.getName()
3.获得节点属性
.attributes()
4.获得节点text
.getText()
下面是一个读取xml数据的例子
@Test
public void xmlRead() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/main/resources/blog-data.xml"));
Element root = document.getRootElement();
System.out.println("当前节点名称:" + root.getName());
List<Attribute> list = root.attributes();
for(Attribute attribute : list) {
System.out.println("属性名" + attribute.getName() + ",值" + attribute.getValue());
}
List<Element> elements = root.elements();
for (Element element : elements) {
System.out.println("当前节点名称:" + element.getName());
List<Element> elements2 = element.elements();
for (Element element2 : elements2){
System.out.println("当前节点名称:" + element2.getName());
System.out.println("当前节点数据:" + element2.getText());
}
}
}
运行结果