当前位置: 首页 > 面试题库 >

使用Jackson将XML属性添加到手动构建的节点树

司宏伯
2023-03-14
问题内容

我正在尝试设置代码来创建节点树Jackson,然后可以使用该树来编写JSONXML。我已经手动创建了节点树,如下所示:

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的某些部分,我想向其中一个节点添加属性,如下所示:

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

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


问题答案:

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

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>

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



 类似资料:
  • 我有一个XML: 我想向根元素:/doc添加一个属性(名称空间),以便输出如下所示: 我尝试了三种xslt(跳过了默认的“复制所有”部分以减少问题的长度)。 xslt1:见下文,问题在于将空名称空间xmlns=”“添加到/doc的所有子节点(即:/doc/tag1和/doc/tag2) Xslt2:见下文,问题是“ns”被添加到根节点:和 xslt3:请参见下文,问题是报告了错误:未定义名称空间前

  • 问题内容: 我想向现有的xml节点添加属性。我不想向xml文件添加新元素(新节点),我只想添加新属性。我怎样才能做到这一点? 特别是我尝试了以下代码行: 但是我得到以下异常: 问题答案: 在DOM解析器中,这非常容易。获取您的节点,只需使用此功能。 然后最后更新您的文档。像这样..

  • 我正在将XML返回到一个jsp页面。 最终的XML结构如下所示: 的根节点作为向量返回,我使用xtream将其别名为“tasks”,如上图所示。 如何使用XStream实现这一点?我需要使用XSLT文件来转换XML输出吗?完成这一点的最佳方法是什么?

  • 问题内容: 我正在尝试读取xml文件,例如: 这是我到目前为止的代码: 这是我尝试编写此代码的尝试,怎么说都不成功,这就是我开始赏金的原因。这是http://pastebin.com/huKP4KED。 赏金更新: 我确实真的尝试了好几天,但现在没想到会这么难,我会接受有用的链接/书籍/教程,但更喜欢代码,因为我昨天需要这样做。 这是我需要的: 关于上面的xml: 我需要获取标题ID的值 temp

  • 问题内容: 如果我想向根元素记录添加属性,可以从sql端执行此操作吗? 我想产生这样的xml: 问题答案: 使用新的语法: 这会给像 在这里阅读更多关于它的信息: 使用T-SQL创建XML文件的简单示例 将XML序列化与SQL的FOR XML PATH一起使用

  • 我试图添加一个属性到一个节点,它是CDATA的一部分。我的XML是 结果应该是xml 文档节点中的id属性应作为属性添加到CDATA中的节点。 我能够以字段[@name='CDATA']的形式获取CDATA值,但我不确定如何将文档的属性添加到CDATA中。。 谁能给我建议一下怎么做,或者给我指出正确的方向?