首页 > 解决方案 > Java 中的 XPath 表达式,用于获取带有标签的 xml 元素

问题描述

我想从包含 xml 元素的 api 中获取节点。

https://www.w3schools.com/xml/cd_catalog.xml这是 api 的链接。

所以我的Java代码是这样的:

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Test1 {

    public static final String GET_API_URL = "https://www.w3schools.com/xml/cd_catalog.xml";

    public static void main(String[] args) throws IOException, InterruptedException {

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder().GET().header("accept", "application/xml").uri(URI.create(GET_API_URL)).build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        try {
            Reader reader = new StringReader(response.body());
            InputSource inputSource = new InputSource(reader);

            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr = xpath.compile("/CATALOG/CD[COUNTRY='USA' and YEAR>=1995]");
            NodeList list = (NodeList)expr.evaluate(inputSource, XPathConstants.NODESET);
            
            for (int i = 0; i < list.getLength(); i++) {
                Node node = list.item(i);
                System.out.println(node.getTextContent());
            }
        }
        catch (XPathExpressionException e) {
            e.printStackTrace();
        }
    }
}

控制台上的输出应该是这样的:

    <CATALOG>
    <CD>
    <TITLE>1999 Grammy Nominees</TITLE>
    <ARTIST>Many</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Grammy</COMPANY>
    <PRICE>10.20</PRICE>
    <YEAR>1999</YEAR>
    </CD>
    
    
    <CD>
    <TITLE>Big Willie style</TITLE>
    <ARTIST>Will Smith</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1997</YEAR>
    </CD>
    </CATALOG>

使用 xpath 表达式,我只能得到 1995 年及以后发布的 cd 值,但没有 xml 标签。

我的控制台输出是这样的:

        1999 Grammy Nominees
        Many
        USA
        Grammy
        10.20
        1999
      
    
        Big Willie style
        Will Smith
        USA
        Columbia
        9.90
        1997

那么关于如何获得完全相同的输出但使用 xml 标签的任何解决方案?如果有人回答,您能否向我解释您的步骤或方法在代码中是如何工作的,抱歉,这里是初学者,我有很多内容要介绍:-) 提前致谢。

标签: javaxmlapirestxpath

解决方案


Transformer类可以帮助我们实现你想要的

这是一种转换Node为的方法String

private static String nodeToString(Node node) throws TransformerException {
    StringWriter res = new StringWriter();
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.transform(new DOMSource(node), new StreamResult(res));
    return res.toString();
}

你可以这样称呼它

System.out.println(nodeToString(node));

推荐阅读