【问题标题】:List of elements into object对象中的元素列表
【发布时间】:2022-08-14 14:51:05
【问题描述】:

我有一些结构

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JacksonXmlRootElement(localName = \"dataModel\")
public class DataModel {

    @JacksonXmlProperty(localName = \"group\")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Group> group;
...

}

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Group {

    @JacksonXmlProperty(localName = \"element\")
    @JacksonXmlElementWrapper(useWrapping = false, localName = \"elements\")
    private List<Element> elements;

   ....
}

@Data
@EqualsAndHashCode
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Element implements Cloneable {

    @JacksonXmlProperty(isAttribute = true, localName = \"name\")
    private String name;
    @JacksonXmlProperty(isAttribute = true, localName = \"value\")
    private String value;
}

这很好用,但我想将我的列表更改为新的类元素

class Elements {

        private List<Element> elements = new ArrayList<>();
}

我必须如何更改我的注释才能完成这项工作?

添加。这是我的 XML 的一部分。也许您对 OBIP 有所了解,它就是由它创建的。 Oracle BI Publisher... 听起来像这样。

<?xml version = \'1.0\' encoding = \'utf-8\'?>

<dataModel xmlns=\"http://xmlns.oracle.com/oxp/xmlp\" version=\"2.0\" xmlns:xdm=\"http://xmlns.oracle.com/oxp/xmlp\" xmlns:xsd=\"http://wwww.w3.org/2001/XMLSchema\">
   
     <group name=\"G_1\" label=\"G_1\" source=\"control_subject_params\">
          <element name=\"PARAM_NAME\" value=\"PARAM_NAME\" label=\"PARAM_NAME\" dataType=\"xsd:string\" breakOrder=\"\" fieldOrder=\"1\"/>
          <element name=\"PARAM_VAL\" value=\"PARAM_VAL\" label=\"PARAM_VAL\" dataType=\"xsd:string\" breakOrder=\"\" fieldOrder=\"2\"/>
    </group>

</dataModel>

有任何想法吗? 实际上我可以将列表更改为组

  • 你能附上你正在解析的 XML(或它的相关部分)吗?
  • @Jonasz 它来自文件,但我包含了其中的一部分

标签: java jackson xml-parsing


【解决方案1】:

我认为创建这样的包装器不能由 Jackson 仅基于注释开箱即用,因此需要自定义 Deserializer

private static final TypeReference<List<Element>> ELEMENT_LIST_TYPEREF =
        new TypeReference<>() {};

@Override
public Group deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
    // Elements class is fully managed by the deserializer here
    // that's why there are no annotations in places where it occurs in the code
    var elements = new Elements();
    var elementNodes = parser.readValueAsTree()
                             .get("element");
    try (var traverse = elementNodes.traverse(parser.getCodec())) {
        List<Element> elementsList = traverse.readValueAs(ELEMENT_LIST_TYPEREF);
        elements.setElements(elementsList);
    }
    var group = new Group();
    group.setElements(elements);
    return group;
}

带有反序列化器的模块可以像这样注册:

var module = new SimpleModule("GroupDeseriaizerModule");
module.addDeserializer(Group.class, new GroupDeserializer());
xmlMapper.registerModule(module);

我们正在为Group 注册一个反序列化器,因为Elements 类是一个人工包装器,它没有用Jackson 注释标记。如果我们确实标记了它,那么解析元素并将其保存为对象可能会更加困难(XML 中的每个element 都是一个单独的反序列化实例)。


Here you can find a repository 我重现了问题并应用了上面显示的解串器代码。 The test 在更改之前通过,现在它也通过了(我必须添加一个额外的提取 .extracting(Group::getElements),因为添加了一个新的包装器)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2014-06-09
    • 2019-05-02
    • 2012-02-19
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多