对于以下示例 XML 输入:
<Participants course="someCourse">
<workers>
<Worker ref="p3">
<Worker ref="p2">
</workers>
<Trainer ref="p1"/>
</Participants>
<Group id="group1" name="some mixed Person group">
<trainers>
<Trainer id="p1" name="John Doe">
</trainers>
<workers>
<Worker id="p2" name="Jim Scott">
<Worker id="p3" name="Walter Peace">
</workers>
</Group>
我试图确保 Participants 中的 PersonList 指向从 group1 读取的 Persons。(有关使用的 JaxB 注释,请参阅下面的代码片段)。这只是我正在寻求的更通用方法的一个示例。我通常需要能够以列表元素正确解组为引用的方式遵循 id="" 和 ref="" 属性。
通过 UnmarshalListener 和 Unmarshalling 两次,我解决了从 ref 属性到 id 属性的引用问题。在第一阶段,查找映射由 id 属性填充。在第二阶段查找裁判。不幸的是,此解决方案将创建副本而不是引用。我可以使用父对象来解决这个问题,但我正在寻找更通用的解决方案。以所示方式使用 ref/id 属性实现正确取消引用的好方法是什么?
/**
* intercept the unmarshalling
*/
public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener {
public Map<String,Person> lookup=new HashMap<String,Person>();
@Override
public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) {
if (target instanceof Person) {
person=(Person) target;
if (person.getId()!=null) {
lookup.put(person.getId(), person);
}
if (person.getRef()!=null) {
if (lookup.containsKey(person.getRef())) {
Person personRef=lookup.get(person.getRef());
person.copyFrom(personRef);
person.setRef(null);
}
}
}
}
}
@XmlRootElement(name="Participants")
public class Participants {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* @return workers
*/
@XmlElementWrapper(name="workers")
@XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
@XmlRootElement(name="Group")
public class Group {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* @return workers
*/
@XmlElementWrapper(name="workers")
@XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
@XmlRootElement(name="Trainer")
public class Trainer extends Person {}
@XmlRootElement(name="Worker")
public class Worker extends Person {}
@XmlRootElement(name="Person")
public class Person {
private String name;
/**
* getter for xsd:string/String name
* @return name
*/
@XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
private String ref;
/**
* getter for xsd:string/String id
* @return id
*/
@XmlAttribute(name="ref")
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref=ref;
}
private String id;
/**
* getter for xsd:string/String id
* @return id
*/
@XmlAttribute(name="id")
@XmlID
public String getId() {
this.id;
}
/**
* setter for xsd:string/String id
* @param pid - new value for id
*/
public void setId(String pid) {
this.id=pid;
}
}