Reputation: 75
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
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