我在解析XML的两种方式一文中,详细介绍了两种两种解析方法:
- 树形解析
- 流机制解析
同样,在本文中,我仍然会介绍两种机制生成XML文档的方法。个人认为,由于生成XML文档的代码过于繁琐,故除一些特殊情形,人为制作XML文档可能比代码生成速度更快。anyway,下面还是一一介绍两种不同生成XML文档的方式。
写树形结构
这种方式的基本思路为,先搭建起Document对象,然后将Document对象的结构和内容写入XML文件中。
以写如下所示的XML为例:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE Log SYSTEM "log.DTD">
<Log>
<!--log filename-->
<Filename extension="xml" type="log">java</Filename>
<!--log limit,must between 10485760(10M) and 52428800(50M)-->
<Limit>20971520</Limit>
<!--log count,cannot be lower than 1-->
<Count>100</Count>
<!--whether to follow the existing file to write,just allow 'TRUE' or 'FALSE' and case insensitive-->
<isAppend>true</isAppend>
<!--Whether to compress the log,just allow 'True' or 'FALSE' and case insensitive-->
<isCompress>true</isCompress>
</Log>
实现的代码如下:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import javax.xml.transform.TransformerException;
public class xmlTest
{
public static void main(String[] args) throws ParserConfigurationException,TransformerFactoryConfigurationError,TransformerConfigurationException,TransformerException
{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.newDocument();//首先创建一个Document对象
doc.setXmlVersion("1.0");//设置文档版本号
doc.setXmlStandalone(false);//false表示需要校验XML,否则不需要校验XML,关于XML文档校验,[验证XML文档](https://editor.csdn.net/md/?articleId=106038399)一文有详细介绍
Element root=doc.createElement("Log");//创建元素
doc.appendChild(root);//添加根元素
root.appendChild(doc.createComment("log filename"));//创建注释,并添加注释
Element filename=doc.createElement("Filename");
filename.setAttribute("extension","xml");//设置元素Filename属性
filename.setAttribute("type","log");
filename.appendChild(doc.createTextNode("java"));//设置元素Filename的文本内容
root.appendChild(filename);
root.appendChild(doc.createComment("log limit,must between 10485760(10M) and 52428800(50M)"));
Element limit=doc.createElement("Limit");
limit.appendChild(doc.createTextNode("20971520"));
root.appendChild(limit);
root.appendChild(doc.createComment("log count,cannot be lower than 1"));
Element count=doc.createElement("Count");
count.appendChild(doc.createTextNode("100"));
root.appendChild(count);
root.appendChild(doc.createComment("whether to follow the existing file to write,just allow 'TRUE' or 'FALSE' and case insensitive"));
Element append=doc.createElement("isAppend");
append.appendChild(doc.createTextNode("true"));
root.appendChild(append);
root.appendChild(doc.createComment("Whether to compress the log,just allow 'True' or 'FALSE' and case insensitive"));
Element compress=doc.createElement("isCompress");
compress.appendChild(doc.createTextNode("true"));
root.appendChild(compress);
TransformerFactory transFactory=TransformerFactory.newInstance();
Transformer transformer=transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,"log.DTD");//设置XML文档文档类型定义文件
transformer.setOutputProperty(OutputKeys.INDENT,"yes");//是否缩进
transformer.setOutputProperty(OutputKeys.METHOD,"xml");//生成xml
transformer.transform(new DOMSource(doc),new StreamResult(new File("./logConfig.xml")));//将Document对象的结构和内容写入xml文件
}
}
StAX
StAX没有缩进的功能,所以由StAX生成的XML文件,元素之间凑在一起。
以生成如下内容的XML文件为例:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE SYSTEM "log.DTD"><Log><!--log filename--><Filename extension="xml" type="log">java</Filename><!--log limit,must between 10485760(10M) and 52428800(50M)--><Limit>20971520</Limit><!--log count,cannot be lower than 1--><Count>100</Count><!--whether to follow the existing file to write,just allow 'TRUE' or 'FALSE' and case insensitive--><isAppend>true</isAppend><!--Whether to compress the log,just allow 'True' or 'FALSE' and case insensitive--><isCompress>true</isCompress><image path="text.gif"/></Log>
完整的代码如下:
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLStreamException;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
public class xmlTest
{
public static void main(String[] args) throws FactoryConfigurationError,XMLStreamException,FileNotFoundException
{
XMLOutputFactory factory=XMLOutputFactory.newInstance();//创建工厂对象
XMLStreamWriter writer=factory.createXMLStreamWriter(new FileOutputStream("./logConfig.xml"),"UTF-8");//创建XMLStreamWriter对象
writer.writeStartDocument("UTF-8","1.0");//如果需要加编码规则,那么在创建XMLStreamWriter对象时继续指定编码规则,否则报错Underlying stream encoding 'GBK' and input paramter for writeStartDocument() method 'UTF-8' do not match
writer.writeDTD("<!DOCTYPE SYSTEM \"log.DTD\">");//写DTD内容
writer.writeStartElement("Log");//根节点起始标签
writer.writeComment("log filename");//注释
writer.writeStartElement("Filename");//元素Filename起始标签
writer.writeAttribute("extension","xml");//元素属性
writer.writeAttribute("type","log");
writer.writeCharacters("java");//元素文本
writer.writeEndElement();//元素Filename结束标签
writer.writeComment("log limit,must between 10485760(10M) and 52428800(50M)");
writer.writeStartElement("Limit");
writer.writeCharacters("20971520");
writer.writeEndElement();
writer.writeComment("log count,cannot be lower than 1");
writer.writeStartElement("Count");
writer.writeCharacters("100");
writer.writeEndElement();
writer.writeComment("whether to follow the existing file to write,just allow 'TRUE' or 'FALSE' and case insensitive");
writer.writeStartElement("isAppend");
writer.writeCharacters("true");
writer.writeEndElement();
writer.writeComment("Whether to compress the log,just allow 'True' or 'FALSE' and case insensitive");
writer.writeStartElement("isCompress");
writer.writeCharacters("true");
writer.writeEndElement();
writer.writeEmptyElement("image");
writer.writeAttribute("path","text.gif");
writer.writeEndElement();//根节点结束标签
writer.writeEndDocument();
writer.close();
}
}