使用 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 输出是:
My XML output is:
<?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
?
推荐答案
不可能将给定的属性标记为 attribute
因为 ObjectNode
对序列化一无所知.您可以为 POJO
类执行此操作,并且 com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator
仅在 @JacksonXmlProperty(isAttribute = true) 时才会处理它
注释用于给定的属性.我建议为需要属性的元素创建 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
而不是 Examples
对象.
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屋!