在阅读我创建的以下XML文件时遇到问题。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<prsettings>
<prsetting>
<players>
<player>
<lastDateEntered>0</lastDateEntered>
<lastTournament>1</lastTournament>
<playerId>0</playerId>
<playersStatus>unrated</playersStatus>
<playersTag>asfd</playersTag>
<score>5.0</score>
<setsPlayed>0</setsPlayed>
<tourneysWhileInactive>0</tourneysWhileInactive>
</player>
<player>
<lastDateEntered>0</lastDateEntered>
<lastTournament>1</lastTournament>
<playerId>1</playerId>
<playersStatus>unrated</playersStatus>
<playersTag>ba</playersTag>
<score>5.0</score>
<setsPlayed>0</setsPlayed>
<tourneysWhileInactive>0</tourneysWhileInactive>
</player>
<player>
<lastDateEntered>0</lastDateEntered>
<lastTournament>1</lastTournament>
<playerId>2</playerId>
<playersStatus>unrated</playersStatus>
<playersTag>asdgf</playersTag>
<score>5.0</score>
<setsPlayed>0</setsPlayed>
<tourneysWhileInactive>0</tourneysWhileInactive>
</player>
</players>
<challongeApiKey>asbg</challongeApiKey>
<challongeUsername>asf</challongeUsername>
<implementPointDecay>false</implementPointDecay>
<numSetsNeeded>5</numSetsNeeded>
<numTourneysForActive>2</numTourneysForActive>
<numTourneysForInnactive>5</numTourneysForInnactive>
<numTourneysNeeded>5</numTourneysNeeded>
<pointsRemoved>5</pointsRemoved>
<prName>asf</prName>
<removeInnactive>false</removeInnactive>
<showPlacingDiff>false</showPlacingDiff>
<showPointDiff>false</showPointDiff>
<startOfDecay>3</startOfDecay>
</prsetting>
我有一个可观察的PRSetting对象列表,在PRSetting对象中我有一个玩家的ArrayList。这就是我创建POJO文件的原因,在PRSetting对象中我设置的唯一对象如下。
@XmlElementWrapper(name="players")
@XmlElement(name ="player")
private ArrayList<PlayerProfile> playersList = new ArrayList<PlayerProfile>();
这也是我的POJO文件,应该用于编写和读取XML文件。
@XmlRootElement (name = "prsettings")
public class PRSettingsWrapper {
private ObservableList<PRSettings> prList;
@XmlElement(name = "prsetting")
public ObservableList<PRSettings> getPrList(){
return prList;
}
public void setPrList(ObservableList<PRSettings> prList){
this.prList = prList;
}
}
出于某种原因,每当我尝试使用以下代码加载数据时
JAXBContext context = JAXBContext
.newInstance(PRSettingsWrapper.class);
Unmarshaller um = context.createUnmarshaller();
// Reading XML from the file and unmarshalling.
PRSettingsData wrapper = (PRSettingsData) um.unmarshal(file);
prList.clear();
prList.addAll(wrapper.getPrList());
// Save the file path to the registry.
setPrSettingsFilePath(file);
我似乎无法成功将xml文件加载到对象中。文件路径工作正常,但我不确定我做错了什么。
提前感谢您的帮助。
答案 0 :(得分:0)
很抱歉误导你的原因。
问题是由ObservableList引起的;
您可以参考这篇文章: Marshalling ObservableList with JAXB
我修改了上面链接中的代码,以下内容应该可行。
anotherTest.MyContainer
package anotherTest;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "prsettings")
public class MyContainer extends MyObject {
private ObservableList<MyObject> children = FXCollections.observableArrayList();
@XmlElements({ @XmlElement(name = "prsetting", type = MyObject.class) })
public List<MyObject> getChildren() {
return children;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("children:");
for (MyObject node : children) {
sb.append("\n");
sb.append(" " + node.toString());
}
return sb.toString();
}
}
anotherTest.MyObject
package anotherTest;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
@XmlType(name = "Object")
public class MyObject {
private String challongeApiKey;
@XmlElementWrapper(name = "players")
private List<PlayerProfile> player;
public String getChallongeApiKey() {
return challongeApiKey;
}
public void setChallongeApiKey(String challongeApiKey) {
this.challongeApiKey = challongeApiKey;
}
public List<PlayerProfile> getPlayer() {
return player;
}
public void setPlayers(List<PlayerProfile> player) {
this.player = player;
}
}
anotherTest.PlayerProfile
package anotherTest;
public class PlayerProfile {
private int playerId;
private String playersStatus;
public int getPlayerId() {
return playerId;
}
public void setPlayerId(int playerId) {
this.playerId = playerId;
}
public String getPlayersStatus() {
return playersStatus;
}
public void setPlayersStatus(String playersStatus) {
this.playersStatus = playersStatus;
}
}
anotherTest.Example
package anotherTest;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Example {
public static void main(String[] args) {
// create container with list
MyContainer container = new MyContainer();
// add objects
MyObject object;
object = new MyObject();
object.setChallongeApiKey("ABCABC");
container.getChildren().add(object);
PlayerProfile p = new PlayerProfile();
p.setPlayerId(1);
p.setPlayersStatus("unrated");
List<PlayerProfile> l = new ArrayList<>();
l.add(0, p);
object.setPlayers(l);
// marshal
String baseXml = marshal(container);
// unmarshal
container = unmarshal(baseXml);
System.out.println("unmarshal test: " + container.getChildren().get(0).getChallongeApiKey());
System.out.println("unmarshal test: " + container.getChildren().get(0).getPlayer().get(0).getPlayerId());
System.out.println("unmarshal test: " + container.getChildren().get(0).getPlayer().get(0).getPlayersStatus());
System.exit(0);
}
public static String marshal(MyContainer base) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(MyContainer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter stringWriter = new StringWriter();
jaxbMarshaller.marshal(base, stringWriter);
String xml = stringWriter.toString();
System.out.println("XML:\n" + xml);
return xml;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static MyContainer unmarshal(String xml) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(MyContainer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader stringReader = new StringReader(xml);
MyContainer container = (MyContainer) jaxbUnmarshaller.unmarshal(stringReader);
return container;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
控制台中的输出是
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<prsettings>
<prsetting>
<players>
<player>
<playerId>1</playerId>
<playersStatus>unrated</playersStatus>
</player>
</players>
<challongeApiKey>ABCABC</challongeApiKey>
</prsetting>
</prsettings>
unmarshal test: ABCABC
unmarshal test: 1
unmarshal test: unrated
对不起,我也不知道为什么。我测试过如果将孩子声明为List<MyObject>
,它可以正常工作。但是,当涉及ObservableList
时,您必须声明它,或者在解组时会出现NullPointerException
(但是相同的代码在编组时效果很好)。
private ObservableList<MyObject> children = FXCollections.observableArrayList();