这是我第一次写博客,所以可能写得不太好,请大家见谅!!
之前在网上看到了很多java生成xml字符串和创建xml本地文件的文章,但是感觉不太完整和解释不太详细(可能是我没有找到。。。)!
所以我自己总结了一下知识,希望对大家有用,也方便自己查阅!!
这篇博客的思路:
1. 关键代码步骤
2. 代码设计思路
3. 运行的结果图片
4. 完整代码
5. 代码的使用 | 测试
关键代码块:
Dom步骤:
1. 创建DocumentBuilderFactory工厂对象: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance():
2. 通过工厂对象,创建DocumentBuilder制作对象:DocumentBuilder builder = factory.newDocumentBuilder();
3. 通过制作对象,创建一个Document对象:Document document = builder.newDocument();
4. 创建节点:Element root = document.createElement(“节点名称”);
5. 添加节点:Element.appendChild(节点);
6. 节点添加属性:Element.setAttribute(“属性名”,”属性值“);
7. 节点间的内容:Element.setTextContent(“标签间内容”);
转换xml步骤:
1. 创建TransformerFactory工厂对象:TransformerFactory transFactory = TransformerFactory.newInstance();
2. 通过工厂对象, 创建Transformer对象:Transformer transformer = transFactory.newTransformer();
3. 创建DOMSource对象:DOMSource domSource = new DOMSource(document);
4. 创建字节流:ByteArrayOutputStream bos = new ByteArrayOutputStream();
5. Transformer的transform()方法将DOM树转换成XML:Transformer对象.transform(DOMSource对象, new StreamResult(bos));
以上为关键代码,如果大家已经有了自己的思路和想法的话,可以不用再往下看了!!
下面为我自己的代码设计思路(可能不一定很好,所以大家也可用自己的设计)
代码设计思路:
1. 创建类XmlFormat:为xml的格式类,一个XmlFormat代表一个层级
(包含:根节点,层级节点,属性节点,设置节点的内容方法)
2. 创建类XmlHandler:用于生成xml字符串 和 生成xml文件
(包含:XmlFormat的集合,创建dom树的方法,生成xml字符串的方法,生成xml文件的方法,重载两个接口方法)
运行的结果图片:
这是第一种格式的xml图(生成的xml并没有换行,我是手动换的,方便图片制作)
这是第二种格式的xml图(生成的xml并没有换行,我是手动换的,方便图片制作)
这是本地生成的xml
完整代码
XmlFormat类:xml的格式类
import java.util.HashMap;
public class XmlFormat {
//根节点名称
private String rootName;
//层级节点 名称/值 (值可为空。当值为空时,代表节点下带有属性节点。 当值不等于空时,代表该节点直接包含内容,没有属性节点)
private HashMap<String, Object> multiplyNames;
//属性节点 名称/值
private HashMap<String, Object> propertyNames;
/**构造函数
* 参数: 根节点名称
* */
public XmlFormat(String rootName){
this.rootName = rootName;
this.multiplyNames = new HashMap<String, Object>();
this.propertyNames = new HashMap<String, Object>();
}
/**(重载)用于xml层级节点键/值(没有属性节点)
* 参数: 层级节点名称, 层级节点的值
* */
public void setElement(String multiplyName, String multiplyValue) {
this.multiplyNames.put(multiplyName, multiplyValue);
}
/**(重载)用于xml层级节点,属性节点
* 参数: 层级节点名称, 属性节点键/值
* */
public void setElement(String multiplyName, HashMap<String, Object> propertyNames) {
this.multiplyNames.put(multiplyName, null);
this.propertyNames = propertyNames;
}
/**
* getter / setter
* */
......
}
XmlHandler类:用于生成xml字符串 和 生成xml文件
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XmlHandler {
//整个xml的节点数据(把设置的每个层级XmlFormat都添加到这个集合中)
public List<XmlFormat> documentElements = new ArrayList<XmlFormat>();
/** 生成Dom树
* 返回Document(整个Dom Tree)
* */
private Document createDom(){
DocumentBuilderFactory factory = null;
DocumentBuilder builder = null;
Document document = null;
try {
factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilderFactory工厂对象
builder = factory.newDocumentBuilder(); //通过工厂对象, 创建DocumentBuilder制作对象
document = builder.newDocument(); //通过制作对象, 创建一个Document对象,该对象代表一个XML文件
document.setXmlStandalone(true); //设置XMLstandalone, true为没有dtd和schema作为该XML的说明文档
//创建根节点
Element root = document.createElement(documentElements.get(0).getRootName());
document.appendChild(root);
//循环创建整个DOM树
for(int i = 0; i < documentElements.size(); i++){
XmlFormat format = documentElements.get(i); //获取xml的一个完整层级
//循环创建层级节点
for(Entry<String, Object> entryMultiply : format.getMultiplyNames().entrySet()){
if(entryMultiply.getValue() != null && !entryMultiply.getValue().toString().equalsIgnoreCase("")){ // 层级节点键/值(没有属性节点)
Element multiplyNode = document.createElement(entryMultiply.getKey()); // 创建一个层级节点
multiplyNode.setTextContent(entryMultiply.getValue().toString()); // 设置该层级节点的值
root.appendChild(multiplyNode);
} else { // 层级节点键(带有属性节点)
Element multiplyNode = document.createElement(entryMultiply.getKey()); // 创建一个层级节点
root.appendChild(multiplyNode);
//循环创建属性节点
for(Entry<String, Object> entryProperty : format.getPropertyNames().entrySet()){
Element propertyNode = document.createElement(entryProperty.getKey()); // 创建一个属性节点
propertyNode.setTextContent(entryProperty.getValue().toString()); // 设置该属性节点的值
multiplyNode.appendChild(propertyNode);
}
root.appendChild(multiplyNode); //设置层级节点到根节点
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
/** 生成xml字符串
* 参数: Document树对象
* 返回String: 整个xml字符串
* */
private String createXmlToString(Document document){
String xmlString = null;
try {
// 创建TransformerFactory工厂对象
TransformerFactory transFactory = TransformerFactory.newInstance();
// 通过工厂对象, 创建Transformer对象
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
//使Xml自动换行, 并自动缩进
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //中间的参数网址固定写法(这里还没搞懂)
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //是否设置缩进(indent: yes|no)
// 创建DOMSource对象并将Document加载到其中
DOMSource domSource = new DOMSource(document);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 使用Transformer的transform()方法将DOM树转换成XML
transformer.transform(domSource, new StreamResult(bos));
xmlString = bos.toString();
} catch (TransformerException e) {
e.printStackTrace();
}
return xmlString;
}
/** 生成xml文件
* 参数: url存放文件路径, Document树对象
* 返回String: 反馈信息
* */
private String createXmlToFile(String url, Document document){
String message = null;
try{
// 创建TransformerFactory对象
TransformerFactory transFactory = TransformerFactory.newInstance();
// 创建Transformer对象
Transformer transformer = transFactory.newTransformer();
//使Xml自动换行, 并自动缩进
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //中间的参数网址固定写法(这里还没搞懂)
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //是否设置缩进(indent: yes|no)
// 建DOMSource对象并将Document加载到其中
DOMSource domSource = new DOMSource(document);
//生成xml文件
File file = new File(url);
if (!file.exists()) { //判断文件是否存在
file.createNewFile(); //不存在生存文件
}
FileOutputStream out = new FileOutputStream(file); //文件输出流
StreamResult xmlResult = new StreamResult(out); //设置输入源
// 使用Transformer的transform()方法将DOM树转换成XML(参数:DOMSource, 输入源)
transformer.transform(domSource, xmlResult);
message = "生成本地XML成功!";
}catch(Exception e){
e.printStackTrace();
message = "生成本地XML失败!";
}
return message;
}
/** 接口方法(重载)
* 创建Xml字符串
* 返回String: xml字符串
* */
public String createXml(){
String xmlString = null;
if(documentElements != null && documentElements.size() > 0){ //判断是否存在xml格式和内容
Document document = createDom(); //调用 生成Dom树 的方法
xmlString = createXmlToString(document); //调用 生成xml字符串 的方法
}
return xmlString;
}
/** 接口方法(重载)
* 创建Xml本地文件(参数: 路径)
* 返回String: 成功/失败消息
* */
public String createXml(String url){
String xmlMessage = null;
if(documentElements != null && documentElements.size() > 0){ //判断是否存在xml格式和内容
Document document = createDom(); //调用 生成Dom树 的方法
xmlMessage = createXmlToFile(url, document); //调用 生成xml文件 的方法
}
return xmlMessage;
}
}
代码的使用 | 测试
//方法使用1(该方法为第一张结果截图,每个层级节点下,带有属性节点)
public static void main(String[] args) {
//创建数据(这里大家可以从数据库读出)
String rootName = "rootXml"; //根节点名称
String multiplyOne = "multiply"; //层级节点名称
HashMap<String, Object> propertyOnes = new HashMap<String, Object>(); //属性节点集合
propertyOnes.put("name", "chuck");
propertyOnes.put("age", 20);
String multiplyTwo = "multiply2"; //层级节点名称
HashMap<String, Object> propertyTwos = new HashMap<String, Object>(); //属性节点集合
propertyTwos.put("name", "Jack");
propertyTwos.put("age", 50);
//创建Xmlformat格式类: 一个Xmlformat为一个层级(以下有两个层级,大家可以回到上面看结果截图)
XmlFormat xmlformatOne = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatOne.setElement(multiplyOne, propertyOnes); //设置层级节点名称 和 属性节点的集合 (setElement为重载方法)
XmlFormat xmlformatTwo = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatTwo.setElement(multiplyTwo, propertyTwos); //设置层级节点名称 和 属性节点的集合(setElement为重载方法)
//创建XmlHandler
XmlHandler xmlhandler = new XmlHandler();
xmlhandler.documentElements.add(xmlformatOne); //把格式XmlFormat, 设置xmlhandler里面的集合
xmlhandler.documentElements.add(xmlformatTwo); //把格式XmlFormat, 设置xmlhandler里面的集合
String xmlString = xmlhandler.createXml(); //调用xmlHandler的接口方法, 获取xml字符串
System.out.println(xmlString);
}
//方法使用2(该方法为第二张结果截图,有一个层级节点下,直接带有内容,没有属性节点)
public static void main(String[] args) {
//创建数据(这里大家可以从数据库读出)
String rootName = "rootXml"; //根节点名称
String multiplyOne = "multiply"; //层级节点名称
String multiplyOneValue = "hello multiply!"; //层级节点内容(没有属性节点)
String multiplyTwo = "multiply2"; //层级节点名称
HashMap<String, Object> propertyTwos = new HashMap<String, Object>(); //属性节点集合
propertyTwos.put("name", "Jack");
propertyTwos.put("age", 50);
//创建Xmlformat格式类: 一个Xmlformat为一个层级(以下有两个层级,大家可以回到上面看结果截图)
XmlFormat xmlformatOne = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatOne.setElement(multiplyOne, multiplyOneValue); //设置层级节点名称 和 层级节点内容 (setElement为重载方法)
XmlFormat xmlformatTwo = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatTwo.setElement(multiplyTwo, propertyTwos); //设置层级节点名称 和 属性节点的集合(setElement为重载方法)
//创建XmlHandler
XmlHandler xmlhandler = new XmlHandler();
xmlhandler.documentElements.add(xmlformatOne); //把格式XmlFormat, 设置xmlhandler里面的集合
xmlhandler.documentElements.add(xmlformatTwo); //把格式XmlFormat, 设置xmlhandler里面的集合
String xmlString = xmlhandler.createXml(); //调用xmlHandler的接口方法, 获取xml字符串
System.out.println(xmlString);
}
//方法使用3(该方法为最后两张结果截图,生成xml本地文件)
public static void main(String[] args) {
//创建数据(这里大家可以从数据库读出)
String rootName = "rootXml"; //根节点名称
String multiplyOne = "multiply"; //层级节点名称
String multiplyOneValue = "hello multiply!"; //层级节点内容(没有属性节点)
String multiplyTwo = "multiply2"; //层级节点名称
HashMap<String, Object> propertyTwos = new HashMap<String, Object>(); //属性节点集合
propertyTwos.put("name", "Jack");
propertyTwos.put("age", 50);
//创建Xmlformat格式类
XmlFormat xmlformatOne = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatOne.setElement(multiplyOne, multiplyOneValue); //设置层级节点名称 和 层级节点内容 (setElement为重载方法)
XmlFormat xmlformatTwo = new XmlFormat(rootName); //创建xml格式,并传入 根节点名称
xmlformatTwo.setElement(multiplyTwo, propertyTwos); //设置层级节点名称 和 属性节点的集合
//创建XmlHandler
XmlHandler xmlhandler = new XmlHandler();
xmlhandler.documentElements.add(xmlformatOne); //把格式XmlFormat, 设置xmlhandler里面的集合
xmlhandler.documentElements.add(xmlformatTwo); //把格式XmlFormat, 设置xmlhandler里面的集合
//调用xmlHandler的接口方法, 获取xml字符串(createXml重载方法,参数传入url)
String xmlString = xmlhandler.createXml("D:\\Learn\\abc.xml");
System.out.println(xmlString);
}