使用Jackson将XML属性添加到手动构建的节点树中 [英] Using Jackson to add XML attributes to manually-built node-tree
问题描述
我正在尝试使用Jackson
设置代码来创建节点树,然后可以将其用于写入JSON
或XML
.我像这样手动创建了节点树:
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屋!