2016-03-09 211 views
0

我試圖將任何給定的xml轉換爲哈希映射。我知道這可以以某種方式使用JAXB完成。我正在嘗試使用jsoup。我的代碼是下面將xml轉換爲java hashmap jsoup

public static Map<String,Object> xmlToMapAll(String xml){ 
      List<Map<String,Object>> list = new ArrayList<Map<String,Object>>(); 
      Map<String,Object> map = new HashMap<String,Object>(); 
      try{ 
       Document xmlDoc = Jsoup.parse(xml, "", Parser.xmlParser()); 
       Elements eles =xmlDoc.getAllElements(); 
       for(Element ele: eles){ 
        Map<String,Object> mi = new HashMap<String,Object>(); 
        if(ele.children().size()>1){ 
         mi = getChilds(ele.children()); 
        }else{ 
         mi.put(ele.tagName(), ele.ownText()); 
        } 
        list.add(mi); 
        //map.putAll(mi); 
       } 

       map.put("data", list); 
       map.put("Status", "SUCCESS"); 
      }catch(Exception ce){ 
       log.error("IndoXMLParseUtil.xmlToMapAll() ce "+IndoUtil.getFullLog(ce)); 
      } 
      return map; 
     } 
     public static Map<String,Object> getChilds(Elements childs){ 
      Map<String,Object> map = new HashMap<String,Object>(); 
      for(Element child: childs){ 
       if(child.children().size()>0){ 
        map = getChilds(child.children()); 
       }else{ 
        map.put(child.tagName(), child.ownText()); 
       } 
      } 
      return map; 
     } 

    public static void main(String args[]){ 
      String xml="<ExtMessage xmlns=\"com/test/schema/evExtQMainPkgQuotaResp\"> 
<ExtQMainPkgQuotaResp>  
<ServiceNumber>1234567</ServiceNumber> 
<Source><a>10</a><b>11</b><a>12</a></Source> 
<Status>Success</Status> 
    <ErrorMessage/><InitialQuota>2621440</InitialQuota> 
     <UsedQuota>62859.49</UsedQuota> 
    </ExtQMainPkgQuotaResp> </ExtMessage> "; 
       Map<String, Object> ds = xmlToMapAll(xml); 
       System.out.println("IndoXMLParseUtil.main() "+ds); 
      } 

輸出:

{狀態= SUCCESS,數據= [{#根=},{extmessage =},{errormessage的=,B = 11, 狀態=成功,a = 12,initialquota = 2621440,usedquota = 62859.49}, {servicenumber = 6285770355730},{b = 11,a = 12},{a = 10},{b = 11},{a = 12} , {status = Success},{errormessage =},{initialquota = 2621440}, {usedquota = 62859.49}]}

問題是我得到重複的數據。我相信在這裏總會有更好的想法。

+0

不知道檢查已經但這應該幫助http://stackoverflow.com/questions/1537207/how-to-convert-xml-to-java-util-map-and-vice-versa及使用jaxb http://stackoverflow.com/questions/27547292/how-to-parse-xml-to-hashmap –

+0

調查XStream。如果這很容易讓你知道。 – Aadam

+0

K我已經使用了一個X Stream示例與XML中給出的問題。這不能完全解析我的XML。就像我們需要提供根元素和別名等一樣。問題是我的XML在運行時不斷變化。我只需要一些可以直接在java對象中表示XML的東西。我不想更改或修改它。 – Aadam

回答

0

這是一個使用W3C DOM解析器的簡單示例,所以有很多可以改進的地方。

此外,您必須定義一個標準來解決可能的密鑰重疊。通過此代碼,只有<Source>的最後<a>將保存到地圖中。如果

public static Map<String, Object> xmlToMapAll(String xml) throws ParserConfigurationException 
{ 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 

    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); 
    Map<String, Object> map = new HashMap<String, Object>(); 
    try 
    { 
     InputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8")); 

     Document xmlDoc = db.parse(stream); 

     Element rootNode = xmlDoc.getDocumentElement(); 

     NodeList eles = rootNode.getChildNodes(); 

     for (int i = 0; i < eles.getLength(); i++) 
     { 
      Node ele = (Node) eles.item(i); 

      Map<String, Object> mi = new HashMap<String, Object>(); 

      if (ele.getChildNodes().getLength() > 1 && ele.getNodeType() == Node.ELEMENT_NODE) 
      { 
       mi.put(ele.getNodeName(), getChilds(ele.getChildNodes())); 
      } 
      else 
      { 
       Node subChild = ele.getFirstChild(); 

       if (subChild != null) 
       { 
        if (!subChild.hasChildNodes()) 
        { 
         mi.put(ele.getNodeName(), subChild.getNodeValue()); 
        } 
        else 
        { 
         mi.put(ele.getNodeName(), ""); 
        } 
       } 
      } 

      if (!mi.isEmpty()) 
      { 
       list.add(mi); 
      } 
     } 

     map.put("data", list); 
     map.put("Status", "SUCCESS"); 
    } 
    catch (Exception ce) 
    { 
     log.error("IndoXMLParseUtil.xmlToMapAll() ce " + IndoUtil.getFullLog(ce)); 
    } 
    return map; 
} 

public static Map<String, Object> getChilds(NodeList childs) 
{ 
    Map<String, Object> map = new HashMap<String, Object>(); 
    for (int a = 0; a < childs.getLength(); a++) 
    { 
     Node child = (Node) childs.item(a); 

     if (child.getNodeType() == Node.ELEMENT_NODE) 
     { 
      if (child.getChildNodes().getLength() > 1) 
      { 
       map.put(child.getNodeName(), getChilds(child.getChildNodes())); 
      } 
      else 
      { 
       Node subChild = child.getFirstChild(); 

       if (subChild != null && !subChild.hasChildNodes()) 
       { 
        map.put(child.getNodeName(), subChild.getNodeValue()); 
       } 
       else 
       { 
        map.put(child.getNodeName(), ""); 
       } 
      } 
     } 
    } 
    return map; 
} 

public static String getNodeValue(Node node) 
{ 
    String result = ""; 

    final NodeList childs = node.getChildNodes(); 

    for (int i = 0; i < childs.getLength(); i++) 
    { 
     final Node child = childs.item(i); 
     if (child != null) 
     { 
      if ((child.getNodeType() == Node.TEXT_NODE) || (child.getNodeType() == Node.CDATA_SECTION_NODE)) 
      { 
       result += child.getNodeValue().trim(); 
      } 
     } 
    } 
    return result; 
}