我正在用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>
答案 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>