JMXB unmarshal возвращает элемент без полномочий root

Я пытаюсь использовать JAXB Unmarshaller для перевода XML-документа в дерево объектов Java.

XML-документ выглядит следующим образом:

<levels>
 <level>
 <solution>
 <piece x="0" y="1">
 <shape>
 <color>
 </color></shape></piece>
 <piece x="0" y="1">
 <shape>
 <color>
 </color></shape></piece>
 </solution>
 <clues>
 <clue>
 <piece x="0" y="0">
 <shape>
 <color>
 </color></shape></piece>
 </clue>
 <clue>
 <piece x="0" y="0">
 <shape>
 <color>
 </color></shape></piece>
 </clue>
 </clues>
 </level>
</levels>

Я создал очень простые классы для хранения каждого компонента:

Levels.java:

@XmlRootElement
public class Levels {

 private List<level> levels = new ArrayList<level>();

 @XmlElementRef(name="Level")
 public List<level> getLevels() {
 return levels;
 }

 public void setLevels(List<level> levels) {
 this.levels = levels;
 }
}
</level></level></level></level>

Level.java:

@XmlRootElement(name="Levels")
public class Level {

 private Solution solution = new Solution();
 private Clues clues = new Clues();

 @XmlElementRef(name="Solution")
 public Solution getSolution() {
 return solution;
 }

 public void setSolution(Solution solution) {
 this.solution = solution;
 }

 @XmlElementRef(name="Clues")
 public Clues getClues() {
 return clues;
 }

 public void setClues(Clues clues) {
 this.clues = clues;
 }
}

Остальные классы отформатированы так же, как и эти (те же аннотации и только методы getter и setter)

Код, который я использую для развязывания xml:

File file = new File("res/levelTest.xml");

JAXBContext jaxbContext = JAXBContext.newInstance(Levels.class); 
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

Object o = jaxbUnmarshaller.unmarshal(file); 
System.out.println(o);

Проблема, которую я получаю, заключается в том, что когда я печатаю объект, он печатает newXML.Solution@*** not newXML.Levels@*** который является корневым элементом. Это означает, что unmarshaller возвращает элемент, отличный от корневого элемента. Я искал google и переполнение стека, но я не мог найти объяснения этого.

Любая помощь приветствуется.

1 ответ

У вас конфликт аннотаций с именем класса верхнего уровня и именем, помещенным в класс Level.

Вы аннотировали свой класс Level с помощью XmlElementRoot, установленного на "Уровни", который на самом деле является корневым элементом для вашего класса Levels. Поскольку вы не указали это явно в своей аннотации для этого класса, привязка JAXB возвращает другое сопоставление для ваших классов.

Я создал быстрый макет вашей программы и смог заставить его работать должным образом со следующим:

Класс уровней:

@XmlRootElement(name="Levels")
public class Levels {


 private List<level> levels = new ArrayList<level>();

 @XmlElementRef(name="Level")
 public List<level> getLevels() {
 return levels;
 }

 public void setLevels(List<level> levels) {
 this.levels = levels;
 }
}
</level></level></level></level>

Класс уровня:

@XmlRootElement(name="Level")
public class Level {

 private Solution solution = new Solution();
 private Clues clues = new Clues();

 @XmlElementRef(name="Solution")
 public Solution getSolution() {
 return solution;
 }

 public void setSolution(Solution solution) {
 this.solution = solution;
 }

 @XmlElementRef(name="Clues")
 public Clues getClues() {
 return clues;
 }

 public void setClues(Clues clues) {
 this.clues = clues;
 }
}

Класс clues (пустой, потому что мне просто нужно определение класса):

@XmlRootElement
public class Clues {
}

Класс решения (тот же, что и выше):

@XmlRootElement
public class Solution {
}

Запуск кода с использованием вашего ввода дает:

Levels@***

licensed under cc by-sa 3.0 with attribution.