Jacksonxml对不连续的内联数组进行格式化

nbysray5  于 7个月前  发布在  其他
关注(0)|答案(2)|浏览(71)

我有一些奇怪的xml我试图将其转换为java对象

<Operator>
    <Parameter Key="a" Value="1"/>
    <Parameter Key="b" Value="2"/>
    <Parameter Key="c" Value="3"/>
    <StorageParameters Key="x" Value="***"/>
    <Parameter Key="d" Value="4"/>
</Operator>

我只需要将参数节点收集为列表。我编写的java类如下

@JsonIgnoreProperties(ignoreUnknown = true)
public class Operator {
  
    @JacksonXmlProperty(localName="Parameter")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Parameter> parameters;

   public Operator() {
       this.parameters = List.of();
   }

   public List<Parameter> getParameters() {
        return parameters;
    }

    public void setParameters(List<Parameter> parameters) {
        this.parameters = parameters;
    }
}

public class Parameter {
    private String Key;
    private String Value;

    public Parameter() {
        Key = "";
        Value = " ";
    }

    public String getKey() {
        return  Key;
    }

    public void setKey(String key) {
        Key = key;
    }

    public String getValue() { return Value; }

    public void setValue(String value) {
        Value = value;
    }
}

// Driver

JacksonXmlModule module = new JacksonXmlModule();
XmlMapper mapper = new XmlMapper(module);

Operator bean = mapper.readValue(xmlText, classOf[Operator])

当我运行这个时,参数列表返回的唯一值是Key=“d”和Value=“4”的最后一个参数条目。
这是预期的行为吗?是否有任何注解可以用来获取所有参数键/值对?
谢谢你,谢谢

35g0bw71

35g0bw711#

这里的问题是<StorageParameters Key="x" Value="***"/>标记的存在:Jackson库期望在列表中仅对 n<Parameter/>相等标签的存在进行分类,但却发现不同的标签并因此决定将该列表解释为不同的属性,所以最后一个<Parameter Key="d" Value="4"/>覆盖了Parameter属性的前一个值,(另一个StorageParameters被忽略,因为Operator类中有JsonIgnoreProperties(ignoreUnknown = true)注解)。
为了避免这种行为,你可以删除不需要的StorageParameters,并解析旧的xml,然后创建一个没有不需要的标签的新xml,如下所示:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new FileInputStream(xml));
Node node = doc.getElementsByTagName("StorageParameters").item(0);
node.getParentNode().removeChild(node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
StringWriter writer = new StringWriter();
t.transform(new DOMSource(doc), new StreamResult(writer));
String result = writer.getBuffer().toString();
Operator value = mapper.readValue(result, Operator.class);

您必须在Parameter中使用JacksonXmlProperty(isAttribute = true)注解来指示值是属性:

@Data
public class Parameter {

    @JacksonXmlProperty(isAttribute = true)
    private String Key;
    @JacksonXmlProperty(isAttribute = true)
    private String Value;
}

@Data
public class Operator {

    @JacksonXmlProperty(localName = "Parameter")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Parameter> parameters;
}
2w3kk1z5

2w3kk1z52#

你可以像这里一样使用@JsonMergeHow to deserealize multiple nested elements in Jackson?
在您的案例中:

@Data
public class Parameter {

    @JacksonXmlProperty(isAttribute = true)
    private String Key;
    @JacksonXmlProperty(isAttribute = true)
    private String Value;
}

@Data
public class Operator {

    @JacksonXmlProperty(localName = "Parameter")
    @JacksonXmlElementWrapper(useWrapping = false)
    @JsonMerge                                     // this should solve your problem
    private List<Parameter> parameters;
}

相关问题