一、前言
由于开发需求,需要定制化xml文件。考虑到xml类似map的键值对原理,因此将数据先封装成map,再将map转换为xml。由于xml有顺序而已,因此要保证数据封装成map时是有序的,于是采用了LinkedHashMa
-
二、思路(递归)
-
2.1Xml的生成使用Document类
-
该类有以下几个主要的方法
Element rootElement = Doc. addElement :创建根元素
Element chridElement = Element.addElement :创建父元素对应的子元素
Element. addAttribute :添加元素的属性
Element.setText :设置元素的值
-
2.2.使用迭代器Iterator,依次拿出map中的值
-
①当key所以对应的value数据类型为LinkedHashMap(因为这里嵌套的时LinkedHashMap,如果是其他类型也可以,比如json),说明还有嵌套的map,于是将key设为父节点,接着进入循环当key所对应的value数据类型为string 的时候,说明为子节点,进行值的设置。
-
三、特殊情况
-
下面是做项目的时候遇到的特殊情况,进行了特殊处理。当然,应该有其他解法
3.1.两个子标签一样
-
- Xml文件要求
-
<Receivers>
<Receiver>WHGGPT</Receiver>
<Receiver>WHGGPT</Receiver>
</Receivers>
因为map规定key值不可以相同,所以我的想法是,在map的时候设置类似的值,然后根据Recrivers进行判断
-
- Map方面的设置
-
Map<String,String> Receivers = new LinkedHashMap<String,String>();
Receivers.put("Receivers1", Receivers1);
Receivers.put("Receivers2", Receivers2);
-
- 取值的处理
-
if(key.startsWith("Receivers")){ //特殊处理,传输xml多个接收者的情况
Element keyElement = rootElement.addElement("Receiver");
keyElement.setText( (String) map.get(key));
}
3.2.父标签和子标签一样
①xml要求
<ApplyDetail>
<ApplyDetail>
…………………..
</ApplyDetail>
</ApplyDetail>
②Map方面无需处理
③取值处理,添加多一个父节点就可以
if(key.equals("ApplyDetail")){ //特殊处理
Element keyElement0 = rootElement.addElement(key);
Element keyElement = keyElement0.addElement(key);
Map map2 = (Map) map.get(key);
loopMap(map2,keyElement);
}
四、完整代码
package com.ceb.test.xmltest;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;
import com.ceb.createxml.DeclareXml;
import com.ceb.createxml.MaptoXml;
public class TestSmart {
public static void main(String[] args){
Map<String,Object> map = new LinkedHashMap<String,Object>();
Map<String,String> head = new LinkedHashMap<String,String>();
Map<String,Object> Declaration = new LinkedHashMap<String,Object>();
Map<String,String> Register = new LinkedHashMap<String,String>();
String MessageType = "00001"; //设置该xml的类型,可以忽略
String Version = "1.0";
head.put("MessageType",MessageType);
head.put("Version",Version);
String Name ="我是name";
String note = "我是note";
Register.put("Name",Name);
Register.put("note", note);
Declaration.put("Register",Register);
map.put("Head",head);
map.put("Declaration",Declaration);
File file = new File("F:/textxml.xml");
TestSmarMll.generDeclareXml(file,map,"00001");
}
}
package com.ceb.test.xmltest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import com.ceb.createxml.MaptoXml;
public class TestSmarMll {
public static void generDeclareXml(File file, Map map, String xmltype) {
Document doc = DocumentHelper.createDocument();//获取Document对象
Element rootElement = doc.addElement(xmltype);
rootElement.addAttribute("xsi:noNamespaceSchemaLocation","xx.xsd");
rootElement.addAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
MaptoXml.loopMap(map, rootElement);
XMLWriter writer;
try {
writer = new XMLWriter(new FileOutputStream(file),
MaptoXml.getForm());
writer.setEscapeText(false);// 字符是否转义,默认true
writer.write(doc);
writer.close();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.ceb.createxml;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import sun.misc.BASE64Encoder;
public class MaptoXml {
/**
* 将map依照层次转化
* @param map
* @param rootElement
*/
public static void loopMap(Map map,Element rootElement){
Iterator<String> it = map.keySet().iterator();
while(it.hasNext()){
String key = it.next();
String typeName =map.get(key).getClass().getName();
System.out.println(key);
System.out.println(getType(typeName));
if(!getType(typeName).equals("LinkedHashMap")){
//if(!getType(typeName).equals("JSONObject")){
if(key.startsWith("Receivers")){ //特殊处理,传输xml多个接收者的情况
Element keyElement = rootElement.addElement("Receiver");
keyElement.setText( (String) map.get(key));
}
else{
Element keyElement = rootElement.addElement(key);
keyElement.setText((String) map.get(key));
}
}
else if(getType(typeName).equals("LinkedHashMap")){
//else if(getType(typeName).equals("JSONObject")){
if(key.equals("ApplyDetail")){ //特殊处理
Element keyElement0 = rootElement.addElement(key);
Element keyElement = keyElement0.addElement(key);
Map map2 = (Map) map.get(key);
loopMap(map2,keyElement);
}
else{
Element keyElement = rootElement.addElement(key);
Map map2 = (Map) map.get(key);
loopMap(map2,keyElement);
}
}
}
}
/**
* 获取数据类型,用于判断是否添加子元素
* @param typeName
* @return
*/
public static String getType(String typeName){
int length= typeName.lastIndexOf(".");
String type =typeName.substring(length+1);
return typeName.substring(length+1);
}
/**
* 解决默认第二行为空的情况
* @return
*/
public static OutputFormat getForm(){
OutputFormat format = OutputFormat.createPrettyPrint();
format.setIndentSize(4);//改为4
format.setNewLineAfterDeclaration(false);
return format;
}
}
四、说明
由于代码是在项目里提取出来的,所有如果那里有错了,运行不了代码,请提问。或者什么对特殊情况改进方法,也多多指点。