Java jackson解析大型JSON为特定的XML数组格式

huangapple go评论51阅读模式
英文:

Java jackson parse large JSON to XML with specific xml array format

问题

帮助我找出如何使用Jackson库将JSON节点转换为XML。我的JSON数据很大(从10到200 MB),包含许多对象。因此,我无法通过类来进行转换,并使用@JacksonXmlProperty(localName = "someName")。因为这个JSON具有许多动态元素。问题在于XML中数组的格式应该是:

<test_data>
     <data_type>numeric</data_type>
     <value>
         <Item>0</Item>
         <Item>1</Item>
     </value>
</test_data>

而JSON元素看起来像这样:

{
     "test_data": {
         "data_type": "numeric",
         "value": [
             0,
             1
         ]
     }
}

如果我们将此XML转换为以下格式:

public static void main(String[] args) throws IOException {
    String xmlStr = """
      <test_data>
        <data_type>numeric</data_type>
        <value>
          <Item>0</Item>
          <Item>1</Item>
        </value>
      </test_data>
    """;
    
    XmlMapper xmlMapper = new XmlMapper();
    JsonNode xml = xmlMapper.readTree(xmlStr);
    ObjectMapper jsonMapper = new JsonMapper();
    System.out.println(jsonMapper.writeValueAsString(xml));
}

输出是:

{"data_type":"numeric","value":{"Item":["0","1"]}}

反之亦然:

String jsonStr = """
    {
        "test_data" : {
                  "data_type" : "numeric",
                  "value" : [ 0, 1 ]
                }
    }
    """;

ObjectMapper jsonMapper = new JsonMapper();
JsonNode node = jsonMapper.readTree(jsonStr.getBytes());
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
String xml = xmlMapper.writeValueAsString(node);
System.out.println(xml);

输出是:

<ObjectNode>
  <test_data>
    <data_type>numeric</data_type>
    <value>0</value>
    <value>1</value>
  </test_data>
</ObjectNode>

简而言之,我有一个JsonNode,我需要具有特定数组格式的XML字符串,有任何想法吗?

尝试找到为JsonNode创建JsonSerializer的方法,但失败了。

英文:

Help me figure out how to convert Jason node to xml with Jacson library.
My JSON is large (from 10 to 200 mb) and contains many objects. So I won’t be able to convert through the class and use @JacksonXmlProperty(localName = &quot;someName&quot;). It because this json has a lotof dynamic elements. And the problem is that the format of arrays in xml should be:

&lt;test_data&gt;
     &lt;data_type&gt;numeric&lt;/data_type&gt;
     &lt;value&gt;
         &lt;Item&gt;0&lt;/Item&gt;
         &lt;Item&gt;1&lt;/Item&gt;
     &lt;/value&gt;
&lt;/test_data&gt;

and jason element looks like this:
{
     &quot;test_data&quot;: {
         &quot;data_type&quot;: &quot;numeric&quot;,
         &quot;value&quot;: [
             0,
             1
         ]
     }
}

if we take this xml and convert it like this:

public static void main(String[] args) throws IOException {
        String xmlStr = &quot;&quot;&quot;
          &lt;test_data&gt;
            &lt;data_type&gt;numeric&lt;/data_type&gt;
            &lt;value&gt;
              &lt;Item&gt;0&lt;/Item&gt;
              &lt;Item&gt;1&lt;/Item&gt;
            &lt;/value&gt;
          &lt;/test_data&gt;
            &quot;&quot;&quot;;
        
        XmlMapper xmlMapper = new XmlMapper();
        JsonNode xml = xmlMapper.readTree(xmlStr);
        ObjectMapper jsonMapper = new JsonMapper();
        System.out.println(jsonMapper.writeValueAsString(xml));
    }

OUTPUT is :

{&quot;data_type&quot;:&quot;numeric&quot;,&quot;value&quot;:{&quot;Item&quot;:[&quot;0&quot;,&quot;1&quot;]}}

visa versa:

String jsonStr = &quot;&quot;&quot;
            {
                &quot;test_data&quot; : {
                          &quot;data_type&quot; : &quot;numeric&quot;,
                          &quot;value&quot; : [ 0, 1 ]
                        }
            }
            &quot;&quot;&quot;;

        ObjectMapper jsonMapper = new JsonMapper();
        JsonNode node = jsonMapper.readTree(jsonStr.getBytes());
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        String xml = xmlMapper.writeValueAsString(node);
        System.out.println(xml);

OUTPUT:

&lt;ObjectNode&gt;
  &lt;test_data&gt;
    &lt;data_type&gt;numeric&lt;/data_type&gt;
    &lt;value&gt;0&lt;/value&gt;
    &lt;value&gt;1&lt;/value&gt;
  &lt;/test_data&gt;
&lt;/ObjectNode&gt;

Simply say, I have JsonNode and I need xml String with specific array format, any idea?

Try find a way to create JsonSerializer for JsonNode but failed.

答案1

得分: 0

我找不到在XmlMapper方面处理它的方法,所以我只是修改了输入的JSON。将所有名称为"value"的数组替换为名称为"value"的对象,并将数组的项复制到新的名称为"Item"的数组中。代码示例如下:

private void changeArrayToObject(JsonNode node) {
    if (node.isObject()) {
        ObjectNode objectNode = (ObjectNode) node;
        Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
        while (iter.hasNext()) {
            Map.Entry<String, JsonNode> entry = iter.next();
            if (entry.getKey().equals("value") && entry.getValue().isArray()) {
                ArrayNode arrayNode = (ArrayNode) entry.getValue();
                ObjectNode newObject = new ObjectNode(new JsonNodeFactory(true));
                entry.setValue(newObject.set("Item", arrayNode));
                if (isArrayValueObjOrNot(arrayNode)) {
                    for (JsonNode nextNode : arrayNode) {
                        changeArrayToObject(nextNode);
                    }
                }
            } else {
                changeArrayToObject(entry.getValue());
            }
        }
    }
}

private Boolean isArrayValueObjOrNot(ArrayNode arrayNode) {
    JsonNode firstElement = arrayNode.get(0);
    return firstElement.isObject();
}
英文:

I didn't find a way to do it on XmlMapper side, so I just modified a input json. Replaced all arrays with name "value" by object with name "value" and copied array`s items to new array with name "Item". code example looks like:

private void changeArrayToObject(JsonNode node) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;
            Iterator&lt;Map.Entry&lt;String, JsonNode&gt;&gt; iter = objectNode.fields();
            while (iter.hasNext()) {
                Map.Entry&lt;String, JsonNode&gt; entry = iter.next();
                if (entry.getKey() == &quot;value&quot; &amp;&amp; entry.getValue().isArray()) {
                    ArrayNode arrayNode = (ArrayNode) entry.getValue();
                    ObjectNode newObject = new ObjectNode(new JsonNodeFactory(true));
                    entry.setValue(newObject.set(&quot;Item&quot;, arrayNode));
                    if(isArrayValueObjOrNot(arrayNode)) {
                        for (JsonNode nextNode : arrayNode) {
                            changeArrayToObject(nextNode);
                        }
                    }
                } else {
                    changeArrayToObject(entry.getValue());
                }
            }
        }
    }

    private Boolean isArrayValueObjOrNot(ArrayNode arrayNode) {
        JsonNode firstElement = arrayNode.get(0);
        if (firstElement.isObject())
            return true;
        return false;
    }

huangapple
  • 本文由 发表于 2023年2月16日 18:40:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定