UchihaMalo
UchihaMalo

Reputation: 75

An XPath expression in Java for getting xml elements with their tags

I want to get nodes from an api which contains xml elements.

https://www.w3schools.com/xml/cd_catalog.xml Here is the link for the api.

So my Java code is like this:

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();
        }
    }
}

The output on the console should be like this:

    <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>

With the xpath expression i get only the cd's values that are released from 1995 and later, but without the xml tags.

My console output is like this:

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

So any solutions on how to get the exact same output but with the xml tags? And if someone answers can you explain to me how your steps or methods are working in the code, sorry for asking but a beginner here and i have a lot of ground to cover :-) Thanks in advance.

Upvotes: 1

Views: 258

Answers (1)

Ahmed HENTETI
Ahmed HENTETI

Reputation: 1128

The Transformer class can help us achieve what you want

Here is a method to transform Node to 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();
}

And you can call it like this

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

Upvotes: 1

Related Questions