Jackson XML 到 JSON 转换器删除了多个子记录
Jackson XML to JSON converter removes multiple child records
我正在使用以下代码将源 XML 转换为 JSON。但是,此代码删除了源 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"
}
]
}
}
如有任何帮助,我们将不胜感激。谢谢!
问题是XML没有区分"Objects"(在JSON术语中,即key/value对的集合)和"Arrays"(没有名称的有序值序列)。使用数据绑定 (POJO) 时,可以根据 Java 类型确定特定 XML 元素表示的是哪个类型——如果 Java 属性 是 List
或数组,它必须是 "Array"; otherwise "Object" —— 但是当只告诉 mapper 将 XML 映射到 java.util.Map
时,没有这样的区别,默认处理基本上会考虑所有 XML 元素来指示 "Objects".由于 "Objects" 不能有重名的属性,因此只保留其中一个值(最后一个)。
没有简单的方法可以避免使用 XmlMapper
:您将需要某种自定义处理。
我能够通过使用 org.json API to convert source XML to 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"
} ]
}
}
}
这可以通过更新到 Jackson 版本 2 来解决。12.x
如果使用 Maven,可以更新版本,将 属性 添加到 pom.xml
<properties>
<jackson-bom.version>2.12.4</jackson-bom.version>
</properties>
此处提供了有关库改进的更多详细信息 - https://cowtowncoder.medium.com/jackson-2-12-improved-xml-b9487889a23f
我正在使用以下代码将源 XML 转换为 JSON。但是,此代码删除了源 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"
}
]
}
}
如有任何帮助,我们将不胜感激。谢谢!
问题是XML没有区分"Objects"(在JSON术语中,即key/value对的集合)和"Arrays"(没有名称的有序值序列)。使用数据绑定 (POJO) 时,可以根据 Java 类型确定特定 XML 元素表示的是哪个类型——如果 Java 属性 是 List
或数组,它必须是 "Array"; otherwise "Object" —— 但是当只告诉 mapper 将 XML 映射到 java.util.Map
时,没有这样的区别,默认处理基本上会考虑所有 XML 元素来指示 "Objects".由于 "Objects" 不能有重名的属性,因此只保留其中一个值(最后一个)。
没有简单的方法可以避免使用 XmlMapper
:您将需要某种自定义处理。
我能够通过使用 org.json API to convert source XML to 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"
} ]
}
}
}
这可以通过更新到 Jackson 版本 2 来解决。12.x
如果使用 Maven,可以更新版本,将 属性 添加到 pom.xml
<properties>
<jackson-bom.version>2.12.4</jackson-bom.version>
</properties>
此处提供了有关库改进的更多详细信息 - https://cowtowncoder.medium.com/jackson-2-12-improved-xml-b9487889a23f