Java读取多层级xml⽂件
最近在做国际客服北京职场的项⽬,需要提供⼀个接⼝服务端的能⼒,也就是需要开发⼀个http+xml的协议,⼊参和出参均为Map 格式,各系统间的请求或应答是以xml格式封装的。在将返回报⽂(xml)解析为Map输出时遇到⼀个难点:Java对于多层级xml的解析。现以⼀个客户资料查询接⼝为例将解析过程记录如下:
返回xml报⽂的简化形式:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<HEAD>
<ORIGIN_DOMAIN>kefuxitongbianma</ORIGIN_DOMAIN>
<HOME_DOMAIN>CUGCRM</HOME_DOMAIN>
<ACTION_CODE>1</ACTION_CODE>
<BUSI_CODE>QUERYCUST</BUSI_CODE>
<TRANS_ID>20160220160635123456</TRANS_ID>
<RET_CODE>0000</RET_CODE>
<RET_MSG>success</RET_MSG>
</HEAD>
<BODY>使用dom4j解析xml文件
<TOTAL_RECORDS>20</TOTAL_RECORDS>
<TOTAL_PAGE>10</TOTAL_PAGE>
<CURRENT_PAGE>1</CURRENT_PAGE>
<CUSTINFOLIST>
<CUSTINFO>
<CUST_TYPE>001</CUST_TYPE>
<VIP_FLAG>true</VIP_FLAG>
</CUSTINFO>
<CUSTINFO>
<CUST_TYPE>002</CUST_TYPE>
<VIP_FLAG>false</VIP_FLAG>
</CUSTINFO>
<CUSTINFO>
<CUST_TYPE>003</CUST_TYPE>
<VIP_FLAG>false</VIP_FLAG>
</CUSTINFO>
</CUSTINFOLIST>
</BODY>
</ROOT>
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
/**
* 解析xml的⼯具类
* 1、将多层级xml解析为Map
* 2、将多层级xml解析为Json
*
* @author lmb
*
*/
*/
public class ParseXmlUtil {
public static Logger logger = Logger(ParseXmlUtil.class);
public static void main(String[] args) {
// 获取⼀个xml⽂件
String textFromFile = MyXmlUtil.XmlToString();
//将xml解析为Map
Map resultMap = xml2map(textFromFile);
//将xml解析为Json
String resultJson = xml2Json(textFromFile);
}
/**
* 将xml格式响应报⽂解析为Json格式
* @param responseXmlTemp
* @return
*/
public static String xml2Json(String responseXmlTemp) {
Document doc = null;
try {
doc = DocumentHelper.parseText(responseXmlTemp);
} catch (DocumentException e) {
<("parse text error : " + e);
}
Element rootElement = RootElement();
Map<String,Object> mapXml = new HashMap<String,Object>();
element2Map(mapXml,rootElement);
String jsonXml = JSONObject.fromObject(mapXml).toString();
System.out.println("Json >>> " + jsonXml);
return jsonXml;
}
/**
* 将xml格式响应报⽂解析为Map格式
* @param responseXmlTemp
* @param thirdXmlServiceBean
* @return
* @throws DocumentException
*/
public static Map<String, Object> xml2map(String responseXmlTemp) {
Document doc = null;
try {
doc = DocumentHelper.parseText(responseXmlTemp);
} catch (DocumentException e) {
<("parse text error : " + e);
}
Element rootElement = RootElement();
Map<String,Object> mapXml = new HashMap<String,Object>();
element2Map(mapXml,rootElement);
System.out.println("Map >>> " + mapXml);
return mapXml;
}
/**
* 使⽤递归调⽤将多层级xml转为map
* @param map
* @param rootElement
*/
public static void element2Map(Map<String, Object> map, Element rootElement) {
//获得当前节点的⼦节点
List<Element> elements = rootElement.elements();
if (elements.size() == 0) {
//没有⼦节点说明当前节点是叶⼦节点,直接取值
map.Name(),Text());
}else if (elements.size() == 1) {
}else if (elements.size() == 1) {
//只有⼀个⼦节点说明不⽤考虑list的情况,继续递归
Map<String,Object> tempMap = new HashMap<String,Object>();
element2Map((0));
map.Name(),tempMap);
}else {
//多个⼦节点的话就要考虑list的情况了,特别是当多个⼦节点有名称相同的字段时
Map<String,Object> tempMap = new HashMap<String,Object>();
for (Element element : elements) {
tempMap.Name(),null);
}
Set<String> keySet = tempMap.keySet();
for (String string : keySet) {
Namespace namespace = (0).getNamespace();
List<Element> sameElements = rootElement.elements(new QName(string,namespace)); //如果同名的数⽬⼤于1则表⽰要构建list
if (sameElements.size() > 1) {
List<Map> list = new ArrayList<Map>();
for(Element element : sameElements){
Map<String,Object> sameTempMap = new HashMap<String,Object>();
element2Map(sameTempMap,element);
list.add(sameTempMap);
}
map.put(string,list);
}else {
//同名的数量不⼤于1直接递归
Map<String,Object> sameTempMap = new HashMap<String,Object>();
element2Map((0));
map.put(string,sameTempMap);
}
}
}
}
}
xml⽂件读取⼯具类:
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
* 读取⼀个xml⽂件返回string
* @author lmb
*
*/
public class MyXmlUtil {
/**
* 加载xml⽂件
* @return Document
*/
public static Document load(){
Document document=null;
String url="E://2.xml";
try {
SAXBuilder reader = new SAXBuilder();
document=reader.build(new File(url));
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
/**
* 将xml⽂件转换为String串
* @return
*/
public static String XmlToString(){
Document document=null;
document=load();
Format format =PrettyFormat();
format.setEncoding("UTF-8");//设置编码格式
StringWriter out=null; //输出对象
String sReturn =""; //输出字符串
XMLOutputter outputter =new XMLOutputter();
out=new StringWriter();
try {
outputter.output(document,out);
} catch (IOException e) {
e.printStackTrace();
}
String();
return sReturn;
}
}
控制台打印结果:
Map >>> {BODY={TOTAL_RECORDS={TOTAL_RECORDS=20}, CUSTINFOLIST={CUSTINFO=[{CUST_TYPE={CUST_TYPE=001}, VIP_FLAG={VIP_FLA
Json >>> {"BODY":{"TOTAL_RECORDS":{"TOTAL_RECORDS":"20"},"CUSTINFOLIST":{"CUSTINFO":[{"CUST_TYPE":{"CUST_TYPE":"001"},"VIP_FLAG":{"VIP_F
格式化之后的结果如下:
map :
{
BODY={
TOTAL_RECORDS={TOTAL_RECORDS=20},
CUSTINFOLIST={
CUSTINFO=[
{
CUST_TYPE={CUST_TYPE=001},
VIP_FLAG={VIP_FLAG=true}
},
{
CUST_TYPE={CUST_TYPE=002},
VIP_FLAG={VIP_FLAG=false}
},
{
CUST_TYPE={CUST_TYPE=003},
VIP_FLAG={VIP_FLAG=false}
}
]
},
TOTAL_PAGE={TOTAL_PAGE=10},
CURRENT_PAGE={CURRENT_PAGE=1}
},
HEAD={
ACTION_CODE={ACTION_CODE=1},
ORIGIN_DOMAIN={ORIGIN_DOMAIN=kefuxit},
BUSI_CODE={BUSI_CODE=QUERYCUST},
HOME_DOMAIN={HOME_DOMAIN=CUGCRM},
TRANS_ID={TRANS_ID=20160220160635123456}, RET_MSG={RET_MSG=success},
RET_CODE={RET_CODE=0000}
}
}
Json:
{
"BODY":{
"TOTAL_RECORDS":{"TOTAL_RECORDS":"20"}, "CUSTINFOLIST":{
"CUSTINFO":[
{
"CUST_TYPE":{"CUST_TYPE":"001"},
"VIP_FLAG":{"VIP_FLAG":"true"}
},
{
"CUST_TYPE":{"CUST_TYPE":"002"},
"VIP_FLAG":{"VIP_FLAG":"false"}
},
{
"CUST_TYPE":{"CUST_TYPE":"003"},
"VIP_FLAG":{"VIP_FLAG":"false"}
}
]
},
"TOTAL_PAGE":{"TOTAL_PAGE":"10"},
"CURRENT_PAGE":{"CURRENT_PAGE":"1"}
},
"HEAD":{
"ACTION_CODE":{"ACTION_CODE":"1"},
"ORIGIN_DOMAIN":{"ORIGIN_DOMAIN":"kefuxit"}, "BUSI_CODE":{"BUSI_CODE":"QUERYCUST"},
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论