2016-04-04 34 views
4

我正在使用以下代碼將我的源XML轉換爲JSON。但是,此代碼將刪除源XML中的任何多次子記錄,並且輸出JSON只包含最後一個子記錄。Jackson XML到JSON轉換器刪除多個子記錄

如何將Jackson XML轉換爲JSON轉換器以輸出JSON中的所有子記錄?

代碼

XmlMapper xmlMapper = new XmlMapper(); 
Map entries = xmlMapper.readValue(new File("source.xml"), LinkedHashMap.class); 
ObjectMapper jsonMapper = new ObjectMapper(); 
String json = jsonMapper.writer().writeValueAsString(entries); 
System.out.println(json); 

源XML

<?xml version="1.0" encoding="ISO-8859-1"?> 
<File> 
    <NumLeases>1</NumLeases> 
    <FLAG>SUCCESS</FLAG> 
    <MESSAGE>Test Upload</MESSAGE> 
    <Lease> 
    <LeaseVersion>1</LeaseVersion> 
    <F1501B> 
     <NEDOCO>18738</NEDOCO> 
     <NWUNIT>0004</NWUNIT> 
     <NTRUSTRECORDKEY>12</NTRUSTRECORDKEY> 
    </F1501B> 
    <F1501B> 
     <NEDOCO>18739</NEDOCO> 
     <NWUNIT>0005</NWUNIT> 
     <NTRUSTRECORDKEY>8</NTRUSTRECORDKEY> 
    </F1501B> 
    </Lease> 
</File> 

實際輸出

{ 
    "NumLeases": "1", 
    "FLAG": "SUCCESS", 
    "MESSAGE": "Test Upload", 
    "Lease": { 
    "LeaseVersion": "1", 
    "F1501B": { 
     "NEDOCO": "18739", 
     "NWUNIT": "0005", 
     "NTRUSTRECORDKEY": "8" 
    } 
    } 
} 

期望輸出

{ 
    "NumLeases": "1", 
    "FLAG": "SUCCESS", 
    "MESSAGE": "Test Upload", 
    "Lease": { 
    "LeaseVersion": "1", 
    "F1501B": [ 
     { 
     "NEDOCO": "18738", 
     "NWUNIT": "0004", 
     "NTRUSTRECORDKEY": "12" 
     }, 
     { 
     "NEDOCO": "18739", 
     "NWUNIT": "0005", 
     "NTRUSTRECORDKEY": "8" 
     } 
    ] 
    } 
} 

任何幫助,將不勝感激。謝謝!

回答

5

我能夠通過使用org.json API將源XML轉換爲JSONObject,然後通過Jackson API轉換爲JSON,從而獲得解決此問題的方案。

代碼

import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 

import org.apache.commons.io.IOUtils; 
import org.json.JSONObject; 
import org.json.XML; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializationFeature; 

... 
... 

try (InputStream inputStream = new FileInputStream(new File(
       "source.xml"))) { 
    String xml = IOUtils.toString(inputStream); 
    JSONObject jObject = XML.toJSONObject(xml); 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.enable(SerializationFeature.INDENT_OUTPUT); 
    Object json = mapper.readValue(jObject.toString(), Object.class); 
    String output = mapper.writeValueAsString(json); 
    System.out.println(output); 
} 

... 
... 

源XML

<?xml version="1.0" encoding="ISO-8859-1"?> 
<File> 
    <NumLeases>1</NumLeases> 
    <FLAG>SUCCESS</FLAG> 
    <MESSAGE>Test Upload</MESSAGE> 
    <Lease> 
    <LeaseVersion>1</LeaseVersion> 
    <F1501B> 
     <NEDOCO>18738</NEDOCO> 
     <NWUNIT>0004</NWUNIT> 
     <NTRUSTRECORDKEY>12</NTRUSTRECORDKEY> 
    </F1501B> 
    <F1501B> 
     <NEDOCO>18739</NEDOCO> 
     <NWUNIT>0005</NWUNIT> 
     <NTRUSTRECORDKEY>8</NTRUSTRECORDKEY> 
    </F1501B> 
    </Lease> 
</File> 

輸出

{ 
    "File" : { 
    "NumLeases" : "1", 
    "FLAG" : "SUCCESS", 
    "MESSAGE" : "Test Upload", 
    "Lease" : { 
     "LeaseVersion" : "1", 
     "F1501B" : [ { 
     "NEDOCO" : "18738", 
     "NWUNIT" : "0004", 
     "NTRUSTRECORDKEY" : "12" 
     }, { 
     "NEDOCO" : "18739", 
     "NWUNIT" : "0005", 
     "NTRUSTRECORDKEY" : "8" 
     } ] 
    } 
    } 
} 
0

問題是XML在「對象」(以JSON術語,即鍵/值對的集合)和「數組」(概念的「數組」)(無序名稱的有序值序列)之間沒有區別。在使用數據綁定(POJO)時,可以根據Java類型確定特定XML元素的含義 - 如果Java屬性是List或數組,則必須是「Array」;否則「對象」 - 但是當僅告訴映射器將XML映射到java.util.Map時,不存在這種區別,並且默認處理將基本上考慮所有XML元素以指示「對象」。由於「對象」不能具有重名的屬性,所以只保留其中一個值(最後一個)。

沒有簡單的方法來避免使用XmlMapper:您將需要某種類型的自定義處理。

+0

我理解這個問題的原因,但你可以分享關於如何做這個自定義處理的一些想法?您是否瞭解可解決此問題的其他Java庫(用於XML到JSON的轉換)? – Aman

+0

@Aman不,我不認爲有可能從XML轉換爲JSON,而沒有真正理解結構 - XML和JSON有不同的數據模型,所以你需要幫助轉換。所以我認爲更好的方法是定義實際的Java類來映射XML內容,然後將實例序列化爲JSON。這允許正確處理列表/數組值。給出的例子可以由傑克遜以及許多其他庫(JAXB,XStream,JibX)來處理 - 在非傑克遜案例中,您將使用那些XML和傑克遜JSON輸出。 – StaxMan

+0

我個人認爲在這些情況下「巧妙地」使用數組的XmlMapper會非常方便。 –