对于follwing例如XML输入:JAXB参考解决
<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>
我试图确保该PersonList参与者指向人从组1读取。 (请参阅下面的代码使用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;
}
}
以下问题: http://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-遏制 - 第一 - 然后 - 元帅 - xmlidref - 后续 和这篇文章: http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with.html 可能会提示Xm lAdapter是一种有效的方法... –
[使用JAXB从两个XML文件中交叉引用XmlIDs]的可能的重复(http://stackoverflow.com/questions/5319024/using-jaxb-to-cross-reference-xmlids-from -two-xml-files) –
Blaise感谢你在这里寻找 - 不,它不是那么简单。我一整天都尝试过所有口味的XmlAdapter,但它不起作用。我可能必须扩展这个问题,以便Person是一个基类,并且引用需要指向Person的派生类。我很难让XmlAdapters正确拾取。 –