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

时间:2017-10-10 12:19:28

标签: java arrays json xml

我有一个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"}]}}

7 个答案:

答案 0 :(得分:2)

我对此很迟...但是,使用org.json:

HW02

希望这会有所帮助;)

答案 1 :(得分:1)

基于 Mario 的解决方案,我做了一些更改,特别是针对 Json 对象中的嵌套子项。 xmlJSONObj 是一样的,但 obj 参数是一个 List,其中包含 JSON 子节点的路径,索引参数仅在递归时需要(在第一次执行时应该从 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);

答案 2 :(得分:0)

如果XML标记有一个子标记,它会将此子标记转换为对象而不是数组。但是,如果XML标记具有2个同名的子项,则返回一个数组。

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

答案 3 :(得分:0)

似乎没有开箱即用的方式。 如果稍后在代码中处理json,您可以检查它是JSONObject还是JSONArray。如果你需要以正确的格式从spring mvc rest controller返回json对象,你也可以检查你在处理什么(JSONArray或JSONObject)。当它是JSONObject时,你将不得不用JSONArray用相同的数据替换它。

Test if it is JSONObject or JSONArray

答案 4 :(得分:0)

如果您使用的是 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;
  }
}

它将返回Jackson ObjectNode,其中包含以下json:

{"name":"Stack"}

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

答案 5 :(得分:0)

我使用这两种方法,但是您将必须确定要包装在数组中的字段。 使用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()));
}

答案 6 :(得分:0)

回复此帖子已经很晚了,但是我的解决方案可能会对某人有所帮助。

问题描述:始终将特定的XML标签转换为JSON数组,而不考虑实例数。

传统方式: XML标记的单个实例将始终转换为JSON对象,我们在这里无法执行任何操作。请在下面找到我的解决方案。

我的方法:因此,如果我们总是始终在开头插入一个虚拟的空标签只是为了确保我们有多个相同的XML标签实例,请考虑以上几点。

由于我们在开头添加了一个虚拟对象,因此,如果将XML转换为JSON,则在JSON数组的第0个实例中始终有一个null对象。因此,我们必须使用JSONArray类的.remove(0)方法从数组中删除此空对象。

将所有内容组合在一起,请找到示例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中的“ Item”标签实际上是单个实例,但在输出中却是JSON数组。

快乐编码!!!