XML解析 - 仅从具有特定ID

时间:2015-05-30 04:18:08

标签: java xml dom

我正在用Java构建一个Steam克隆游戏管理器,我在项目的最后一部分遇到了问题。在GUI的左侧,我自动填充了从库XML文件中解析的游戏的“播放列表”,我想通过ListSelectionListener单击该播放列表时从该播放列表中检索游戏。我目前能够通过使用getElementsByTagName(“Game”)来填充存储在库中的所有游戏,但是我需要它们特定于播放列表,该播放列表也被分配了唯一的id,其中attributeID设置为“Id”的真。

但是,在下面的代码中,我需要做一些像readLib.getElementById(id).getChildNodes();但每次我这样做,我都会在那一行得到一个nullpointer异常。有任何想法吗?我觉得我非常接近。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();         String [] gameArray = null;

    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document readLib = builder.parse(LIBRARY_FILE_PATH);
        System.out.println("ID:" + id);
        NodeList gameNodes = readLib.getElementsByTagName("Game");
        gameArray = new String[gameNodes.getLength()];
        for (int i = 0; i < gameNodes.getLength(); i++) {
            Node p = gameNodes.item(i);
            if (p.getNodeType() == Node.ELEMENT_NODE) {
                Element Game = (Element) p;
                String gameNames = Game.getAttribute("Name");
                gameArray[i] = gameNames;
            }
        }
    } catch (ParserConfigurationException e) {
        LogToFile.writeFile("[GM-Logging] Parser configuratoin exception when generating game list");
    } catch (SAXException e) {
        LogToFile.writeFile("[GM-Logging] General SAXException in generateGames() method");
    } catch (IOException e) {
        LogToFile.writeFile("[GM-Logging] IOException while generating game names in Library Manager engine");
    }

这是XML库的示例:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Library>
    <Playlist Id="0" list="First Person Shooters">
        <Game Name="Counter-Strike: Source">
            <Path>C:\\Program Files\\Games\\CSS\cstrike.exe</Path>
            <Executable>cstrike.exe</Executable>
        </Game>
        <Game Name="Counter-Strike: Global Offense">
            <Path>C:\\Program Files\\Games\\CSGO\csgo.exe</Path>
            <Executable>csgo.exe</Executable>
        </Game>
        <Game Name="Crysis 3">
            <Path>C:\\Program Files\\Games\\Crytek\crysislauncher.exe</Path>
            <Executable>crysislauncher.exe</Executable>
        </Game>
    </Playlist>
    <Playlist Id="1" list="Grand Theft Auto Series">
        <Game Name="Grand Theft Auto V">
            <Path>C:\\Program Files\\Games\\Rockstar\gtav.exe</Path>
            <Executable>gtav.exe</Executable>
        </Game>
        <Game Name="Grand Theft Auto IV: Ballad of Gay Tony">
            <Path>C:\\Program Files\\Games\\Rockstar\gtaiv\gtaiv.exe</Path>
            <Executable>gtaiv.exe</Executable>
        </Game>
    </Playlist>
<Playlist Id="2" list="Survival and Horror Games"></Playlist>

2 个答案:

答案 0 :(得分:0)

看看你的xml,下面是我的建议。

创建一个类,

@XmlRootElement(name = "Library")
public class Library {
    private List<Playlist> playlist = new ArrayList<Playlist>();

..... getter 

@XmlElement(name = "Playlist")
public void setPlaylist(List<Playlist> playlist) {
        this.playlist = playlist;
}


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

private Game game;
private String path;
private String executable;

@XmlElement(name = "path")
public void setPath(String path) {
        this.path = path;
}

... similarly write getter and setter for game & executable


}

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

private String name;

@XmlElement(name = "name")
public void setName(String name) {
        this.name = name;
}

... write getter


}

在你的主要班级

JAXBContext jaxbContext = JAXBContext.newInstance(Library.class);

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

String xmlStr = xmlString; // the entire xml as string
            InputStream is = new ByteArrayInputStream(xmlStr.getBytes());

            Library library = (Library) jaxbUnmarshaller.unmarshal(is);

            List<Playlist> playLst = library.getPlayList();

现在你有了解析XML的playLst对象

答案 1 :(得分:0)

我建议调查xpath。这将有助于您获得XML的特定部分,尤其是当您具有比id属性更复杂的过滤器时。我不是一个java人,以下代码基于此构建:How to read XML using XPath in Java

DocumentBuilder builder = factory.newDocumentBuilder();
Document readLib = builder.parse(LIBRARY_FILE_PATH);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//Playlist[@id='" + id + "']/Game");

System.out.println("ID:" + id);
NodeList gameNodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
//the rest can be the same code
.......

关于正在使用的xpath的简短说明:

以上代码生成如下所示的xpath表达式:

//Playlist[@id='certain_id']/Game
  • //Playlist:在XML文档的任何位置找到<Playlist>个元素
  • [@id='certain_id']:过滤仅返回id属性等于"certain_id"的人
  • /Game:来自满足上述条件的每个<Playlist>元素,获取子元素<Game>