Java讀取多層級xml檔案
賢和兄發表於2017-10-23
最近在做國際客服北京職場的專案,需要提供一個介面服務端的能力,也就是需要開發一個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>
- <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.getLogger(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) {
- logger.error("parse text error : " + e);
- }
- Element rootElement = doc.getRootElement();
- 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) {
- logger.error("parse text error : " + e);
- }
- Element rootElement = doc.getRootElement();
- 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.put(rootElement.getName(),rootElement.getText());
- }else if (elements.size() == 1) {
- //只有一個子節點說明不用考慮list的情況,繼續遞迴
- Map<String,Object> tempMap = new HashMap<String,Object>();
- element2Map(tempMap,elements.get(0));
- map.put(rootElement.getName(),tempMap);
- }else {
- //多個子節點的話就要考慮list的情況了,特別是當多個子節點有名稱相同的欄位時
- Map<String,Object> tempMap = new HashMap<String,Object>();
- for (Element element : elements) {
- tempMap.put(element.getName(),null);
- }
- Set<String> keySet = tempMap.keySet();
- for (String string : keySet) {
- Namespace namespace = elements.get(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(sameTempMap,sameElements.get(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 =Format.getPrettyFormat();
- 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();
- }
- sReturn=out.toString();
- return sReturn;
- }
- }
控制檯列印結果:
- 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"},"HOME_DOMAIN":{"HOME_DOMAIN":"CUGCRM"},"TRANS_ID":{"TRANS_ID":"20160220160635123456"},"RET_MSG":{"RET_MSG":"success"},"RET_CODE":{"RET_CODE":"0000"}}}
格式化之後的結果如下:
- <strong>map :</strong>
- {
- 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}
- }
- }
- <strong>Json:</strong>
- {
- "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"}
- }
- }
相關文章
- 讀取xml檔案 解析雙層xml2012-10-15XML
- JAVA 讀取xml檔案2010-12-23JavaXML
- Java系列:讀取XML檔案2021-09-09JavaXML
- C#讀取Xml檔案2018-11-26C#XML
- 用JDOM讀取XML檔案2013-12-20XML
- SaxReader讀取,更新xml檔案2017-11-12XML
- XMl 檔案屬性的讀取2008-09-25XML
- NSXMLDocument讀取遠端XML檔案2012-05-18XML
- Java 讀取檔案2021-01-17Java
- QDomDocument 讀取和編輯xml檔案2019-07-06XML
- Rss-Rome 閱讀器讀取XML檔案2010-10-09XML
- java讀取properties檔案2011-10-08Java
- javascript讀取xml檔案程式碼例項2017-03-27JavaScriptXML
- 文摘:在EJB中讀取XML配置檔案2004-11-24XML
- js讀取xml檔案,用了Microsoft.XMLDOM2007-04-25JSXMLROS
- 簡單讀取XML檔案中的值2012-01-09XML
- Java讀取以.xlsx結尾的excel檔案,並寫出每張表對應的c#類、java類、儲存資料的xml檔案、讀取xml檔案的工具類2017-11-16JavaExcelC#XML
- java中讀取配置檔案2018-10-16Java
- Java高效讀取大檔案2015-01-22Java
- Sql server:從XML檔案中讀取配置資訊2009-11-30SQLServerXML
- SQL Server中讀取XML檔案的簡單做法2008-05-26SQLServerXML
- 菜鳥學Java(八)——dom4j詳解之讀取XML檔案2013-08-05JavaXML
- java中讀取.properties配置檔案2016-05-02Java
- Java屬性檔案的讀取2011-06-24Java
- 讀寫iOS XML檔案2016-08-15iOSXML
- java中多種方式讀檔案2007-04-24Java
- java讀取excel層級結構的遞迴寫法2020-09-25JavaExcel遞迴
- 配置檔案讀取——MySQL 多個連線2019-11-01MySql
- Java實時讀取日誌檔案2020-03-01Java
- java讀取大檔案並處理2019-02-20Java
- Java 讀取txt檔案生成Word文件2021-12-03Java
- Java讀取Json檔案工具類2020-12-25JavaJSON
- Java API 讀取HDFS的單檔案2017-05-27JavaAPI
- java讀取resouces目錄下檔案2017-06-15Java
- java讀取大檔案1G+2013-10-30Java
- java mysql儲存和讀取檔案2011-12-11JavaMySql
- 使用 Java 解析XML檔案2022-04-07JavaXML
- c# 讀取多個路徑檔案到一個檔案2014-05-05