无法使用JAXB读取XML文件?

时间:2016-03-07 02:49:45

标签: java xml jaxb

在阅读我创建的以下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文件加载到对象中。文件路径工作正常,但我不确定我做错了什么。

提前感谢您的帮助。

1 个答案:

答案 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();