使用xpath读取多个XML属性

时间:2017-12-20 02:44:21

标签: java xml xpath

所以说我有这样的事情:

<info>
    <collectorKey id="key"/>
    <credentials user="user" password="password"/>
    <Infos>
        <dummyInfo>
            <infoSource temp="N/A">               
                <tags>
                    <tag id="1" value="example"/>
                    <tag id="2" value="example"/>
                    <tag id="3" value="example"/>
                    <tag id="4" value="example"/>
                    <tag id="5" value="example"/>
                    <tag id="6" value="example"/>
                    <tag id="7" value="example"/>
                </tags>
            </infoSource>
        </dummyInfo>
    </Infos>
    <Infos>
        <dummyInfo>
            <infoSource temp="N/A">               
                <tags>
                    <tag id="1" value="example"/>
                    <tag id="2" value="example"/>
                    <tag id="3" value="example"/>
                    <tag id="4" value="example"/>
                    <tag id="5" value="example"/>
                    <tag id="6" value="example"/>
                    <tag id="7" value="example"/>
                </tags>
            </infoSource>
        </dummyInfo>
    </Infos>
</info>

我希望获取ID为2的每个标记属性并获取该标记的值。现在我有一些冗长的代码来做它,它似乎不太实用。 我想将它转换为使用xpath,如果可能的话我想知道如何做到这一点。我把一些骨架代码放在一起,但它并没有用2来标记我的标记值。我假设需要添加一些循环以及一些更改。

类似的东西:

try {
        ClassLoader classLoader = getClass().getClassLoader();
        File configProdXML = new File(classLoader.getResource("files/config-prod.xml").getFile());

        //parse it using a docbuilder
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = null;
        dBuilder = dbFactory.newDocumentBuilder();
        Document parsedConfig = dBuilder.parse(configProdXML);

        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        XPathExpression expr = xpath.compile("/tags/tags/@id=2/text()");

        System.out.println(expr.toString());
旁注。 xpath是最实用的吗?

1 个答案:

答案 0 :(得分:1)

是的,XPath是理想的:

XPathExpression expr = xpath.compile("//tags/tag[@id=2]/@example");

一些解释:

  • //tags中的两个斜杠表示文档中任何位置的所有<tags>元素。
  • tag[@id=2]表示<tag>元素,但带有限制哪些元素符合条件的谓词。

通常,没有必要直接调用XPath.compile,除非您计划将相同的XPath应用于许多不同的源。您可以直接调用evaluate方法:

NodeList values = (NodeList)
    xpath.evaluate("//tags/tag[@id=2]/@example", parsedConfig,
        XPathConstants.NODESET);

注意:永远不要调用URL.getFile()。它不会将URL转换为有效的文件名 - 它只返回主机和端口之后的URL部分,其中可能包含不允许出现在URL中的许多字符的百分比转义。此外,Class.getResource或ClassLoader.getResource返回的URL不保证完全指向文件;特别是,如果您尝试从.jar文件运行,则不会获得file:网址。

幸运的是,您不需要文件。您甚至不需要解析文档。您可以直接将InputStream传递给XPath:

try (InputStream config = getClass().getResourceAsStream("/files/config-prod.xml")) {

    NodeList values = (NodeList)
        xpath.evaluate("//tags/tag[@id=2]/@example", new InputSource(config),
            XPathConstants.NODESET);

    int count = values.getLength();
    for (int i = 0; i < count; i++) {
        String value = values.item(i).getNodeValue();
        System.out.println("Found value \"" + value + "\"");
    }
}