使用Jackson将XML属性添加到手动构建的节点树中 [英] Using Jackson to add XML attributes to manually-built node-tree

查看:548
本文介绍了使用Jackson将XML属性添加到手动构建的节点树中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Jackson设置代码来创建节点树,然后可以将其用于写入JSONXML.我像这样手动创建了节点树:

I'm trying to set up code to create a node tree using Jackson which can then be used to write either JSON or XML. I've created the node tree manually like so:

XmlMapper nodeMapper = new XmlMapper();

ObjectNode rootNode = nodeMapper.createObjectNode();
ObjectNode currentNode = rootNode.putObject("Examples");
currentNode.put("Puppy", TRUE)
           .put("Apple", 2)
           .put("Jet", "Li");
currentNode = rootNode.putObject("Single");
currentNode.put("One", 1);

String writePath = "C:/users/itsameamario/Documents/basicXMLtest.xml";
nodeMapper.writeValue(new File(writePath), rootNode);

我的XML输出是:

<?xml version="1.0"?>
<ObjectNode>
    <Examples>
        <Puppy>true</Puppy>
        <Apple>2</Apple>
        <Jet>Li</Jet>
    </Examples>
    <Single>
        <One>1</One>
    </Single>
</ObjectNode>

但是对于XML的某些部分,我想像这样向其中一个节点添加一个属性:

However for some parts of the XML I would like to add an attribute to one of the nodes like so:

<Examples overlyComplicated="yes">
<!--...-->
</Examples>

我发现的所有包含属性的示例都应用于一个预先存在的类.我无法找到一种将属性添加到如上所述的手动构建的节点树的方法.可以使用Jackson做到吗?

All the examples I've found that include attributes are applied to a pre-existing class. I have been unable to find a method to add attributes to a manually-built node-tree as above. Is it doable using Jackson?

推荐答案

由于ObjectNode对序列化一无所知,因此无法将给定属性标记为attribute.您可以对POJO类执行此操作,并且仅当@JacksonXmlProperty(isAttribute = true)批注用于给定属性时,com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator才会处理它.我建议为需要属性的元素创建POJO并使用Jackson XML批注或实现JsonSerializable接口.可能如下所示:

It is not possible to mark given property as attribute since ObjectNode does not know anything about the serialisation. You can do that for POJO class and com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator will handle it only if @JacksonXmlProperty(isAttribute = true) annotation is used for given property. I suggest to create POJO for element where you need attribute and use Jackson XML annotations or implement JsonSerializable interface. It could look like below:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("Puppy", Boolean.TRUE);
        map.put("Apple", 2);
        map.put("Jet", "Li");
        Examples examples = new Examples();
        examples.setOverlyComplicated("yes");
        examples.setMap(map);

        XmlMapper mapper = new XmlMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        ObjectNode rootNode = mapper.createObjectNode();
        rootNode.putPOJO("Examples", examples);
        ObjectNode currentNode = rootNode.putObject("Single");
        currentNode.put("One", 1);

        mapper.writeValue(System.out, rootNode);
    }
}

class Examples implements JsonSerializable {

    @Override
    public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ToXmlGenerator toXmlGenerator = (ToXmlGenerator) gen;
        toXmlGenerator.writeStartObject();

        writeAttributes(toXmlGenerator);
        writeMap(toXmlGenerator);

        toXmlGenerator.writeEndObject();
    }

    private void writeAttributes(ToXmlGenerator gen) throws IOException {
        if (overlyComplicated != null) {
            gen.setNextIsAttribute(true);
            gen.writeFieldName("overlyComplicated");
            gen.writeString(overlyComplicated);
            gen.setNextIsAttribute(false);
        }
    }

    private void writeMap(ToXmlGenerator toXmlGenerator) throws IOException {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            toXmlGenerator.writeObjectField(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
        serialize(gen, serializers);
    }

    private String overlyComplicated;
    private Map<String, Object> map;

    // getters, setters, toString
}

上面的代码显示:

<ObjectNode>
  <Examples overlyComplicated="yes">
    <Puppy>true</Puppy>
    <Apple>2</Apple>
    <Jet>Li</Jet>
  </Examples>
  <Single>
    <One>1</One>
  </Single>
</ObjectNode>

如果要对JSON序列化使用相同的Example POJO,则需要使用serialize方法处理它,或创建另一个ObjectNode而不是Examlples对象.

In case you want to use the same Example POJO for JSON serialisation you need to handle it in serialize method or create another ObjectNode instead of Examlples object.

这篇关于使用Jackson将XML属性添加到手动构建的节点树中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆