Parsing XML using XPath in Java using Google Geocode - java

kohaNimi = "Tallinn";
URL myUrl = new URL("http://maps.googleapis.com/maps/api/geocode/xml?address=" + kohaNimi + "&sensor=false");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(myUrl.openStream());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("/GeocodeResponse/result/bounds/southwest/lat");
String swLat = expr.evaluate(doc, XPathConstants.STRING).toString();
System.out.println("swLat: " + swLat );
So I am trying to use Google geocode API to get the coordinates of a town, but I have trouble parsing the xml. I am trying to use xPath with Java. I can verify that ... does exist. The problem is that when I try to parse this xml I wont get any text as response. I have looked over the code and can't seem to figure out what is wrong. I used this blogpost to assemble my code: http://tunatore.wordpress.com/2011/05/20/how-to-use-xpath-i-java-simple-example/
You can verify that xpath is correct(should get response) from here: http://maps.googleapis.com/maps/api/geocode/xml?address=Tallinn&sensor=false
Can anyone spot what is wrong?

Change:
xpath.compile("/GeocodeResponse/result/bounds/southwest/lat")
To:
xpath.compile("/GeocodeResponse/result/geometry/bounds/southwest/lat")

Related

Get xml attribute value from string [duplicate]

This question already has answers here:
In Java, how do I parse XML as a String instead of a file?
(6 answers)
Closed 9 years ago.
I'm trying to create a RESTful webservice using a Java Servlet. The problem is I have to pass via POST method to a webserver a request. The content of this request is not a parameter but the body itself.
So I basically send from ruby something like this:
url = URI.parse(#host)
req = Net::HTTP::Post.new('/WebService/WebServiceServlet')
req['Content-Type'] = "text/xml"
# req.basic_auth 'account', 'password'
req.body = data
response = Net::HTTP.start(url.host, url.port){ |http| puts http.request(req).body }
Then I have to retrieve the body of this request in my servlet. I use the classic readline, so I have a string. The problem is when I have to parse it as XML:
private void useXML( final String soft, final PrintWriter out) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException, FileNotFoundException {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(soft);
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("//software/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
out.println(nodes.item(i).getNodeValue());
}
}
The problem is that builder.parse() accepts: parse(File f), parse(InputSource is), parse(InputStream is).
Is there any way I can transform my xml string in an InputSource or something like that? I know it could be a dummy question but Java is not my thing, I'm forced to use it and I'm not very skilled.
You can create an InputSource from a string by way of a StringReader:
Document doc = builder.parse(new InputSource(new StringReader(soft)));
With your string, use something like :
ByteArrayInputStream input =
new ByteArrayInputStream(yourString.getBytes(perhapsEncoding));
builder.parse(input);
ByteArrayInputStream is an InputStream.

Why does Document object not need to be cast when passing to XPathExpression.evalutate method?

I'm doing some work cleaning up working code in an application of mine, and I noticed that I was reusing XPathFactory, XPath, XPathExpression objects in multiple places in my code, and figured I would clean it up and set up a method to do this. What I noticed is that typically when you send the XML document to the XPathExpression.evalutate method that you just place it in the parameter for the source like this.
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
Document builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(new FileReader("/path/to/file.xml"));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expression = xpath.compile("path/to/node");
Object result = expression.evaluate(document, XPathConstants.NODE);
This is fine that it works but when I try to wrap the XPath portion into a separate method like this:
private Object getObjectByExpression(String expr, InputSource source, QName objectType)
{
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expression = xpath.compile(expr);
Object result = expression.evaluate(document, objectType);
return result;
}
public void someCalledMethod()
{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
Document builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(new FileReader("/path/to/file.xml"));
Object result = getObjectByExpression("/path/to/node", document, XPathConstants.NODE);
}
Eclipse tells me that I must cast the document to InputSource and marks it as an error. I did double check that the InputSource used in XPathExpression.evaluate and that in my method are the same class type. Does anyone have a deeper understanding as from where this inconsistency comes?
Actually, with Document it is using XPathExpression.evaluate(Object, QName) method.
Document is an interface, so it can't heritate the class InputSource. It is not possible. This is why you need to update your method :
private Object getObjectByExpression(String expr, Object source, QName objectType)
Or if you really want to limit this to Document
private Object getObjectByExpression(String expr, Document source, QName objectType)

use xpath to extract value from xml file with multiple namespace in java

I am trying to extract node value with multiple namespaces in java but not succeed. The xml file is like:
<ns26:start xmlns:ns26="http://www.tektronix.com/iris/isa/capture/start"
xmlns:ns31="http://www.tektronix.com/iris/isa/filters"
xmlns:ns13="http://www.tektronix.com/iris/isa/monitoredObjects"
xmlns:ns6="http://www.tektronix.com/iris/isa"
xmlns:ns10="http://www.tektronix.com/iris/isa/monNodeObjects"
xmlns:ns7="http://www.tektronix.com/iris/isa/capture/monitoredElements"
xmlns:ns11="http://www.tektronix.com/iris/isa/pointcodes"
xmlns:ns8="http://www.tektronix.com/iris/isa/capture/captureSession"
xmlns:ns2="http://www.tektronix.com/iris/isa/sessionSaveInfo"
xmlns:ns4="http://www.tektronix.com/iris/isa/customData"
xmlns:ns3="http://www.tektronix.com/iris/isa/manifest">
<ns6:Id>LAB:11300/isaclient;440</ns6:Id>
</ns26:start>
I want to extract Id with xpath local-name(). Expression like //*[local-name()='start']/*[local-name()='Id'] but didn't get any matched node. Please help to find issue here. Thanks
Add the java code here:
public static List<String> getXPathValueNamespace(String xml, String expression throws ParserConfigurationException, SAXException, IOException, XPathExpressionException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
List<String> list = new ArrayList<String>();
builder = factory.newDocumentBuilder();
InputSource source = new InputSource(new StringReader(xml));
doc = builder.parse(source);
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile(expression);
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++)
list.add(nodes.item(i).getNodeValue());
return list;
}
The expression //*[local-name()='start']/*[local-name()='Id'] works and for the example document one node should be contained in the result node list.
But you should use nodes.item(i).getTextContent() to retrieve the node content, since getNodeValue() returns null for element nodes.

Reading XML drom webpage returning null

I am using following code to read XML from webpage. I have mentioned public URL here as cant mention project URL:
`String g1="http://www.w3schools.com/xml/note.xml";
DocumentBuilderFactory dbFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder=dbFactory.newDocumentBuilder();
Document doc=dBuilder.parse(g1);`
but I am receiving value of doc as null.
Do something like :-
String urlString = "http://www.w3schools.com/xml/note.xml";
URL url = new URL(urlString);
DocumentBuilderFactory dbFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder=dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(url.openStream());
NodeList descNodes = doc.getElementsByTagName("note");
for(int i=0; i<descNodes.getLength();i++)
{
System.out.println(descNodes.item(i).getTextContent());
}
Output:-
Tove
Jani
Reminder
Don't forget me this weekend!
Refer below link hope it helps you..see the part for 1.2 in it !!
http://viralpatel.net/blogs/java-xml-xpath-tutorial-parse-xml/

Getting parent node content in xml file by java

In XML file a Parent tag has multiple child tag, with content inside.
I need the Parent tag info only,
how to get that:
i.e.,
<main>**Name**
<names>**Harish**</names>
<names2>**Mathi**</names>
</main>
Here i need only "Name". I no need "Harish","Mathi"...
in this case what i have to include in JAVA code...
You can do using XPath:
main/text()
UPDATE:
Example:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("sample.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("main/text()");
Object result = expr.evaluate(doc, XPathConstants.STRING);
System.out.println(result.toString());
OUTPUT:
**Name**

Categories