当只有一个对象Java时,将XML转换为Json数组



我有一个XML,当在XML中有多个元素时,我需要将其转换为JSON。它创建了正确的jsonArray,但当单个元素没有创建数组时,任何一个元素都可以帮助我如何在单个元素的情况下获得数组

String TEST_XML_STRING = "<Items><Item><Name>Stack</Name><Name>OverFlow</Name></Item></Items>";
JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING);
// output - {"Items":{"Item":{"Name":["Stack","OverFlow"]}}}

String TEST_XML_STRING = "<Items><Item><Name>Stack</Name></Item></Items>";
JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING);
// output - {"Items":{"Item":{"Name":"Stack"}}}

但应该是{"Items":{"Item":[{"Name":"Stack"}]}}

我迟到了。。。但是,使用org.json:

public static void forceToJSONArray(JSONObject xmlJSONObj, String obj) throws org.json.JSONException 
{
// where "JSONObject xmlJSONObj" is my JSONObject obtained by passing the XML throug the method toJSONObject 
// and where "String obj" is the name of the JSONObject I want to force to JSONArray
Object myObj = xmlJSONObj.opt(obj);
if (myObj == null)
{
// if my obj doesn't exist inside my xmlJSONObj i create it empty
JSONArray jsonArray = new JSONArray();
xmlJSONObj.put(obj, jsonArray);
}
else if ( myObj instanceof JSONObject ) 
{
// if exist but is a JSONObject, I force it to JSONArray
JSONObject myJSONObj = (JSONObject)myObj;
JSONArray jsonArray = new JSONArray();
jsonArray.put(myJSONObj);
xmlJSONObj.put(obj, jsonArray);
}
else if ( myObj instanceof String || myObj instanceof Integer ) 
{
// if exist but is a primitive entry (like in your case), I force it to a "primitive" JSONArray
JSONArray jsonArray = new JSONArray();
jsonArray.put(myObj);
xmlJSONObj.put(obj, jsonArray);
}  
}

希望这能有所帮助;)

基于Mario的解决方案,我做了一些更改,特别是针对Json对象中的嵌套子对象。xmlJSONObj是相同的,但是obj param是一个List,它包含JSON子级的路径,并且索引param仅是递归所必需的(它应该在第一次执行时从0开始)。

/**
* Forces a JSON Object to be an Array. When converting from XML to JSON, There may be cases in
* which we want a list of elements in the final JSON but there is only one element in the XML
* file, so the XML.toJSONObject method will fail. This methods forces a JSON element to be an
* array instead of just a JSON Object.
* 
* @param xmlJSONObj obtained by passing the XML through the method toJSONObject
* @param obj list of String that contains the path to the JSON child to convert to Array
* @param index required for recursion, starts at 0
* @throws org.json.JSONException
*/
public static void forceToJSONArray(JSONObject xmlJSONObj, List<String> obj, int index)
throws org.json.JSONException {
Object myObj = xmlJSONObj.opt(obj.get(index));
if (myObj instanceof JSONObject && obj.size() == index + 1) {
JSONObject myJSONObj = (JSONObject) myObj;
JSONArray jsonArray = new JSONArray();
jsonArray.add(myJSONObj);
xmlJSONObj.put(obj.get(index), jsonArray);
} else if (myObj instanceof JSONObject) {
forceToJSONArray((JSONObject) myObj, obj, index + 1);
}
}

示例:

我们有这个JSON:

{
"person":{
"name":"Tony",
"data":{
"car":"Toyota"
}
}
}

我们想要这个JSON:

{
"person":{
"name":"Tony",
"data":{
"car":["Toyota"]
}
}
}

我们应该这样调用方法:

forceToJSONArray(xmlJSONObj, Arrays.asList("person", "data", "car"), 0);

如果XML标记只有一个子级,它将把这个子级转换为对象而不是数组。但是,如果XML标记有2个以上同名的子级,它将返回一个数组。

你对此无能为力。唯一的方法是使用另一个库。

似乎没有现成的方法。如果稍后在代码中处理json,则可以检查它是JSONObject还是JSONArray。如果您需要从springmvcrest控制器以正确的格式返回json对象,您也可以检查处理的内容(JSONArray或JSONObject)。当它是JSONObject时,您将不得不用具有相同数据的JSONArray来替换它。

测试是JSONObject还是JSONArray

如果您正在使用Java 8或更高版本,您应该查看我的开源库:unXml。unXml基本上从Xpath映射到Json属性。

它在Maven Central上可用。

示例

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.nerdforge.unxml.factory.ParsingFactory;
import com.nerdforge.unxml.parsers.Parser;
import org.w3c.dom.Document;
public class Parser {
public ObjectNode parseXml(String xml){
Parsing parsing = ParsingFactory.getInstance().create();
Document document = parsing.xml().document(xml);
Parser<ObjectNode> parser = parsing.obj("/Items/Item")
.attribute("name", "Name")
.build();
ObjectNode result = parser.apply(document);
return result;
}
}

它将返回一个JacksonObjectNode,带有以下json:

{"name":"Stack"}

您还可以创建一个解析器,将嵌套的ObjectNodesArrayNodes返回到您想要的任何JSON结构。

我使用这两种方法,但您必须确定要在数组中封装的字段。使用javax.json.*:

private static JsonObject wrapFieldInArray(JsonObject object, String fieldKey) {
JsonValue fieldValue = object.get(fieldKey);
if(fieldValue instanceof JsonObject){
JsonObjectBuilder builder = Json.createObjectBuilder(object);
builder.remove(fieldKey);
builder.add(fieldKey, wrapObjectInArray((JsonObject) fieldValue));
object = builder.build();
}
return object;
}
public static JsonArray wrapObjectInArray(JsonObject obj){
JsonArrayBuilder builder = Json.createArrayBuilder();
builder.add(obj);
return builder.build();
}

使用org.json:

private static JSONObject wrapFieldInArray(JSONObject object, String fieldKey) {
Object fieldValueObj = object.get(fieldKey);
if(fieldValueObj instanceof JSONObject){
JSONObject fieldValue = (JSONObject) fieldValueObj;
object.remove(fieldKey);
object.put(fieldKey, wrapObjectInArray(fieldValue));
}
return object;
}
public static JSONArray wrapObjectInArray(JSONObject obj){
return new JSONArray().put(new JSONObject(obj.toString()));
}

现在回复这篇文章已经很晚了,但我的解决方案可能会对某人有所帮助。

问题描述:无论实例数量如何,始终将特定的XML标记转换为JSON数组。

传统方式:XML标记的单个实例总是会转换为JSON对象,我们在这里什么都做不了。请在下面找到我的解决方案。

我的方法:所以,如果我们总是在开头插入一个伪空标记,只是为了确保我们有多个相同XML标记的实例,请考虑以上这一点。

当我们在开头添加一个伪对象时,如果我们将此XML转换为JSON,那么在JSON数组的第0个实例中总是有一个null对象。因此,我们必须使用JSONArray类的.remove(0)方法从数组中删除这个null对象。

将所有这些结合在一起,请找到示例java代码供您参考。


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;

public class XMLtoJSONConverter {
public static void main(String[] args) {
String xmlData = "<Items><Item><Name>Stack</Name><Name>OverFlow</Name></Item></Items>";
xmlData = xmlData.replaceFirst("<Item>","<Item/><Item>");
try {
JSONObject xmlJSONObj = XML.toJSONObject(xmlData);
JSONArray jsonArray = xmlJSONObj.getJSONObject("Items").getJSONArray("Item");
jsonArray.remove(0);
System.out.println(xmlJSONObj);
} catch (JSONException je) {
System.out.println(je.toString());
}
}
}

输出:

{
"Items":{
"Item":[{
"Name":["Stack","OverFlow"]
}]
}
}

注意:"项目";给定XML中的标记实际上是一个实例,但在输出中却是JSON数组。

编码快乐!!!

最新更新