如何使用错误的父/子模型解组 xml 消息 [英] How to unmarshal xml message with bad parent/child model
问题描述
我正在尝试将第 3 方 XML 有效负载解组到一个类中.问题是有效载荷具有父/子关系,并且根节点、父节点和子节点都具有相同的元素名称.这是有效载荷的示例.
I am trying to unmarshal a 3rd party XML payload into a class. The problem is that the payload has a parent/child relationship and the root node, the parent and the children all have the same element name. Here is a sample of the payload.
<?xml version="1.0" encoding="UTF-8"?>
<Directory>
<id>2</id>
<name>Media</name>
<Directory>
<id>5</id>
<name>Default_Content</name>
<Directory>
<id>9</id>
<name>Images</name>
</Directory>
<Directory>
<id>8</id>
<name>Icons</name>
</Directory>
<Directory>
<id>6</id>
<name>Additional_Content</name>
</Directory>
</Directory>
<Directory>
<id>12</id>
<name>IC</name>
</Directory>
</Directory>
所以我正在尝试注释一个类,以便 JAXB/JAX-RS 可以将其解组为有用的东西.
So I am trying to annotate a class so JAXB/JAX-RS can unmarshal this into something useful.
我尝试过类似的方法
@XmlRootElement(name="Directory")
public class Directory {
private int id;
private String name;
@XmlElement(name="Directory");
private List<Directory> directories = new ArrayList<Directory>();
}
但是,可以预见的是,它会抛出 IllegalAnnotationException
,因为它有 2 个同名的属性.
But, predictably, it throws an IllegalAnnotationException
because of having 2 properties with the same name.
关于如何使用 JAXB/JAX-RS 干净地处理这种混乱的任何想法,还是我应该自己解析它?
Any ideas as to how I can use JAXB/JAX-RS to cleanly handle this mess or should I just parse it on my own?
推荐答案
简答
异常是由于字段/属性冲突.您可以注释属性(获取方法)或在您的类型上设置以下注释:
The exception is due to a field/property collision. You can either annotate the properties (get methods) or set the following annotation on your type:
@XmlAccessorType(XmlAccessType.FIELD)
public class Directory {
...
}
长答案
JAXB 的默认访问类型是 PUBLIC_MEMBER
这意味着 JAXB 将映射所有公共字段(实例变量)和属性(get/set 方法).
JAXB's default access type is PUBLIC_MEMBER
this means that JAXB will map all public fields (instance variables) and properties (get/set methods).
public class Foo {
private String bar;
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
如果你注释一个字段:
public class Foo {
@XmlAttribute
private String bar;
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
那么 JAXB 会认为它有两个 bar
属性映射并抛出异常:
Then JAXB will think it has two bar
properties mapped and thrown an exception:
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "bar"
this problem is related to the following location:
at public java.lang.String example.Foo.getBar()
at example.Foo
this problem is related to the following location:
at private java.lang.String example.Foo.bar
at example.Foo
解决方法是对属性进行注解,设置XmlAccessType类型为FIELD
The solution is to annotate the property and set the XmlAccessType type to FIELD
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
@XmlAttribute
private String bar;
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
你的模型
目录
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Directory")
@XmlAccessorType(XmlAccessType.FIELD)
public class Directory {
private int id;
private String name;
@XmlElement(name="Directory")
private List<Directory> directories = new ArrayList<Directory>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Directory> getDirectories() {
return directories;
}
public void setDirectories(List<Directory> directories) {
this.directories = directories;
}
}
演示
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Directory.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Directory directory = (Directory) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(directory, System.out);
}
}
这篇关于如何使用错误的父/子模型解组 xml 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!