java - XML 解析 - 仅从具有特定 ID 的父节点获取节点

标签 java xml dom

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

但是,在下面的代码中,我需要执行类似 readLib.getElementById(id).getChildNodes(); 的操作;但每次我这样做时,我都会在该行得到一个空指针异常。有任何想法吗?我觉得我已经非常接近了。

DocumentBuilderFactory 工厂 = 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>

最佳答案

我建议查看 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 :查找<Playlist> XML 文档中任意位置的元素
  • [@id='certain_id'] :过滤器仅返回具有 id 的内容属性等于 "certain_id"
  • /Game :来自 <Playlist> 中的每个满足上述条件的元素,获取子元素<Game>

关于java - XML 解析 - 仅从具有特定 ID 的父节点获取节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30542189/

相关文章:

javascript - 快捷方式将 jQuery 限制为特定 DOM 节点

javascript - 如何使用 GTM 显示唯一的 id 值?

java - 将 KeyEvent 与 Java.awt 结合使用

java - 在 XML 文件中的特定位置插入字符串

xml - 所有 XML 文本的 TrimSpaces

javascript - 在Electron BrowserView中访问DOM

java - 如何从 JSON 解析 DiagnosticReport 并再次打印相同的 JSON?

java - 如何使用java生成s3风格的访问/ key

java - 为什么 Stream Parallel() 不使用所有可用线程?

java - xstream - 以 UTF-8 格式保存 XML 的正确方法