【问题标题】:Get Jackson XMLMapper to read root element name获取 Jackson XMLMapper 以读取根元素名称
【发布时间】:2016-03-30 18:42:47
【问题描述】:

如何让 Jackson 的 XMLMapper 在反序列化时读取根 xml 元素的名称?

我将输入 XML 反序列化为通用 Java 类 LinkedHashMap,然后再转换为 JSON。我想在反序列化为 LinkedHashMap 时动态读取输入 XML 的根元素。

代码

XmlMapper xmlMapper = new XmlMapper();
Map entries = xmlMapper.readValue(new File("source.xml"), LinkedHashMap.class);
ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writer().writeValueAsString(entries);
System.out.println(json);

输入 XML

<?xml version="1.0" encoding="ISO-8859-1"?>
<File>
  <NumLeases>1</NumLeases>
  <NEDOCO>18738</NEDOCO>
  <NWUNIT>0004</NWUNIT>
  <FLAG>SUCCESS</FLAG>
  <MESSAGE>Test Upload</MESSAGE>
  <Lease>
     <LeaseVersion>1</LeaseVersion>
     <F1501B>
        <NEDOCO>18738</NEDOCO>
        <NWUNIT>0004</NWUNIT>
        <NTRUSTRECORDKEY>12</NTRUSTRECORDKEY>
     </F1501B>
  </Lease>
</File>

实际输出

{"NumLeases":"1","NEDOCO":"18738","NWUNIT":"0004","FLAG":"SUCCESS","MESSAGE":"Test Upload","Lease":{"LeaseVersion":"1","F1501B":{"NEDOCO":"18738","NWUNIT":"0004","NTRUSTRECORDKEY":"12"}}}  

预期输出(注意:JSON 中有一个名为“File”的根元素)

{"File":{"NumLeases":"1","NEDOCO":"18738","NWUNIT":"0004","FLAG":"SUCCESS","MESSAGE":"Test Upload","Lease":{"LeaseVersion":"1","F1501B":{"NEDOCO":"18738","NWUNIT":"0004","NTRUSTRECORDKEY":"12"}}}}

可能有一些开关可以设置它。任何帮助将不胜感激。

【问题讨论】:

    标签: jackson jackson-dataformat-xml


    【解决方案1】:

    遗憾的是没有标志。它可以通过com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer 的自定义实现来完成。 (Jackson How-To: Custom Deserializers):

    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import com.fasterxml.jackson.dataformat.xml.XmlMapper;
    import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
    import java.io.File;
    import java.io.IOException;
    //...
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.registerModule(new SimpleModule().addDeserializer(JsonNode.class, 
    
        new JsonNodeDeserializer() {
    
            @Override
            public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                String rootName = ((FromXmlParser)p).getStaxReader().getLocalName();
                return ctxt.getNodeFactory()
                        .objectNode().set(rootName, super.deserialize(p, ctxt));
            }
        }));
    
    JsonNode entries = xmlMapper.readTree(new File("source.xml"));
    System.out.println(entries);
    

    【讨论】:

    • 虽然我最初的问题是将 XML 转换为 Map,但您的回答有助于深入了解我的需求。该代码非常适用于 XML 到 JSON 转换器。
    • 我最终将我的 XML 转换为 JSON,因此我相应地编辑了我的问题。谢谢!
    • 这不是默认行为有点烦人。
    猜你喜欢
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多