The code
try{
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/xml?address=Riyadh&sensor=false");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while(null != (line = reader.readLine())){
System.out.println(line);
}
}catch(Exception e){
e.printStackTrace();
}
The output:
Server is Ready....
<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
<status>OK</status>
<result>
<type>locality</type>
<type>political</type>
<formatted_address>Riyadh Saudi Arabia</formatted_address>
<address_component>
<long_name>Riyadh</long_name>
<short_name>Riyadh</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Riyadh Province</long_name>
<short_name>Riyadh Province</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Saudi Arabia</long_name>
<short_name>SA</short_name>
<type>country</type>
<type>political</type>
</address_component>
<geometry>
<location>
<lat>24.7135517</lat>
<lng>46.6752957</lng>
</location>
<location_type>APPROXIMATE</location_type>
<viewport>
<southwest>
<lat>24.2939113</lat>
<lng>46.2981033</lng>
</southwest>
<northeast>
<lat>25.1564724</lat>
<lng>47.3469543</lng>
</northeast>
</viewport>
<bounds>
<southwest>
<lat>24.2939113</lat>
<lng>46.2981033</lng>
</southwest>
<northeast>
<lat>25.1564724</lat>
<lng>47.3469543</lng>
</northeast>
</bounds>
</geometry>
<place_id>ChIJmZNIDYkDLz4R1Z_nmBxNl7o</place_id>
</result>
</GeocodeResponse>
I'm trying to use Google geocode API to get the coordinates of a city, but I'm facing problem that how can i parse the XML response to retrieve the longitude and the latitude of the city enclosed within the (<location></location>) section.
Check the org.w3c.dom.* java library for xml parsing, or JDOM... if you want to access something in a hierarchical way.
Please check XML Parsers in JAVA for more alternatives.
After implementing the code, you just kinda call for the element "location", and iterate through its children and retrieve the values you want.
here's an example:
String xmlRecords = "<data><employee><name>A</name>"
+ "<title>Manager</title></employee></data>";
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("employee");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("name");
Element line = (Element) name.item(0);
System.out.println("Name: " + getCharacterDataFromElement(line));
NodeList title = element.getElementsByTagName("title");
line = (Element) title.item(0);
System.out.println("Title: " + getCharacterDataFromElement(line));
}
}
String xmlRecords = "<data><employee><name>A</name>"
+ "<title>Manager</title></employee></data>";
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("employee");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("name");
Element line = (Element) name.item(0);
System.out.println("Name: " + getCharacterDataFromElement(line));
NodeList title = element.getElementsByTagName("title");
line = (Element) title.item(0);
System.out.println("Title: " + getCharacterDataFromElement(line));
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "";
}
}
Related
I have an xml file as such
<?xml version="1.0" encoding="UTF-8"?>
<folder name="c">
<folder name="program files">
<folder name="uninstall information" />
</folder>
<folder name="users"/>
</folder>
I want to print out "c", "program files", "uninstall information" and "users" what i finally want to do is to print out only values of the name attribute with string starting from u , therefore users and uninsall information.
But i have not been able to print all the values out,
Below is my code where you can see i have tried to ways but no success so far.
public static Collection<String> folderNames(String xml, char startingLetter) throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
FileInputStream fis = new FileInputStream("src/main/resources/test.xml");
org.xml.sax.InputSource is = new InputSource(fis);
Document doc = documentBuilder.parse(is);
NodeList nodeList = doc.getElementsByTagName("*");
for(int i =0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
/// Tried this
if(node.getNodeType() == Node.ELEMENT_NODE) {
String value = node.getTextContent();
System.out.println("value:::" +value);
}
/// tried this
// Element element = (Element)nodeList.item(i);
// NamedNodeMap attributes = element.getAttributes();
// Node nodeValue1 = nodeList.item(i);
// System.out.println(nodeValue1.getAttributes().item(i));
}
} catch (Exception e) {
e.getMessage();
}
return Collections.EMPTY_LIST;
}
for speedy test my imported classes looks like test
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
My approach without using getElementByTagsName
Document doc = documentBuilder.parse(is);
NodeList nodeList = doc.getElementsByTagName("folder");
for(int i =0; i < nodeList.getLength(); i++) {
if (nodeList.item(i).hasChildNodes()) {
for(int i1 = 0; i1 < nodeList.item(i).getChildNodes().getLength(); i1++) {
Node node = nodeList.item(i).getChildNodes().item(i);
System.out.println(node.getAttributes().item(i));
}
}
Node nodeValue1 = nodeList.item(i);
System.out.println(nodeValue1.getAttributes().item(i));
This isnt complete but it will require a recursive call, due to hierarchy in the xml
Example of printing all folder names starting with u:
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<folder name=\"c\">\n" +
" <folder name=\"program files\">\n" +
" <folder name=\"uninstall information\" />\n" +
" </folder>\n" +
" <folder name=\"users\"/>\n" +
"</folder>";
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(xml)));
NodeList nodeList = doc.getElementsByTagName("folder");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String name = element.getAttribute("name");
if (name.startsWith("u"))
System.out.println(name);
}
Output
uninstall information
users
You almost had it. First you have to identify the XML element, which you did.
if(node.getNodeType() == Node.ELEMENT_NODE) {
String value = node.getTextContent();
System.out.println("value:::" +value);
}
but instead of getting invoking getTextContent(), you need to find the attribute in that element. Some variation of the below. Of course, if there is more than one attribute you will need to accomodate looking at them all (using node.getAttributes().getLength()):
if(node.getNodeType() == Node.ELEMENT_NODE) {
if (node.getAttributes() != null) {
String name = node.getAttributes().item(0).getNodeName();
String value = node.getAttributes().item(0).getNodeValue();
System.out.println("attribute name:::" +name + " value:::" +value);
}
}
When parsing the xml, I want to retrieve the token value:
PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|
But I am currently getting the related:
Found attribute: expiry with value: 2014-10-29T22:20:00Z
xml file:
<?xml version="1.0"?>
<Inrix responseId="63448807-78d3-4ee8-90d6-a8b64abff8fc" statusText="" statusId="0" createdDate="2014-10-29T21:21:55Z" versionNumber="5.4" copyright="Copyright INRIX Inc." docType="GetSecurityToken">
<AuthResponse>
<AuthToken expiry="2014-10-29T22:20:00Z">PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|</AuthToken>
<ServerPath>devzone.inrix.com/traffic/inrix.ashx</ServerPath>
<ServerPaths>
<ServerPath region="NA" type="API">http://na.api.inrix.com/Traffic/Inrix.ashx</ServerPath>
<ServerPath region="NA" type="TTS">http://na-rseg-tts.inrix.com/RsegTiles/tile.ashx</ServerPath>
</ServerPaths>
</AuthResponse>
</Inrix>
This is the code I wrote to parse the xml file above:
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder =factory.newDocumentBuilder();
Document document = builder.parse(new File(inputfile));
document.getDocumentElement().normalize();
NodeList AuthTokens = document.getElementsByTagName("AuthToken");
//NodeList AuthTokens = document.getElementsByTagName("ServerPath");
int num = AuthTokens.getLength();
for (int i=0; i<num;i++){
Element node = (Element) AuthTokens.item(i);
NamedNodeMap attributes = node.getAttributes();
int numAttrs = attributes.getLength();
for (int j=0; j<numAttrs;j++){
Attr attr = (Attr) attributes.item(j);
String attrName = attr.getNodeName();
String attrValue = attr.getNodeValue();
System.out.println(attr.getParentNode());
System.out.println("Found attribute: " + attrName + " with value: " + attrValue);
}
}
How do I get the correct value?
I believe you want the contents of the node, not its' attributes. Change your Element to Node and then you can call Node.getTextContent()
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(inputfile));
document.getDocumentElement().normalize();
NodeList AuthTokens = document.getElementsByTagName("AuthToken");
// NodeList AuthTokens = document.getElementsByTagName("ServerPath");
int num = AuthTokens.getLength();
for (int i = 0; i < num; i++) {
Node node = AuthTokens.item(i);
String token = node.getTextContent();
System.out.println(token);
}
Output is (as requested)
PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|
I need to receive all the text alone from an xml file for receiving the specific tag i use this code. But i am not sure how to parse all the text from the XML i the XML files are different i don't know their root node and child nodes but i need the text alone from the xml.
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(streamLimiter.getFile());
doc.getDocumentElement().normalize();
System.out.println("Root element :"
+ doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("employee");
System.out.println("-----------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
NodeList nlList = eElement.getElementsByTagName("firstname")
.item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
System.out.println("First Name : "
+ nValue.getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
Quoting jsight's reply in this post: Getting XML Node text value with Java DOM
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
class Test {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws Exception {
String xml = "<add job=\"351\">\n"
+ " <tag>foobar</tag>\n"
+ " <tag>foobar2</tag>\n"
+ "</add>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
org.w3c.dom.Document doc = db.parse(bis);
Node n = doc.getFirstChild();
NodeList nl = n.getChildNodes();
Node an, an2;
for (int i = 0; i < nl.getLength(); i++) {
an = nl.item(i);
if (an.getNodeType() == Node.ELEMENT_NODE) {
NodeList nl2 = an.getChildNodes();
for (int i2 = 0; i2 < nl2.getLength(); i2++) {
an2 = nl2.item(i2);
// DEBUG PRINTS
System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):");
if (an2.hasChildNodes()) {
System.out.println(an2.getFirstChild().getTextContent());
}
if (an2.hasChildNodes()) {
System.out.println(an2.getFirstChild().getNodeValue());
}
System.out.println(an2.getTextContent());
System.out.println(an2.getNodeValue());
}
}
}
}
}
Output:
#text: type (3):
foobar
foobar
#text: type (3):
foobar2
Adapt this code to your problem and it should work.
I have xml file
<A>
<A1>
<A2>Hi</A2>
</A1>
<A>
<B>
<B1></B1>
<B2>100</B2>
</B>
<A>
<A1>
<A2>Hello</A2>
</A1>
<A>
<B>
<B1>1000</B1>
<B2></B2>
</B>
likewise this goes more than 10 blocks. Now my java code able to read one by one that is first reads all after that reads tag.
Code:
public class XMLParse {
static Document doc;
public static void main(String argv[]) {
try {
File file = new File("/home/dev042/Desktop/xxx.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeLst = doc.getElementsByTagName("A");
System.out.println("Information of all Balence Sheet");
int count = nodeLst.getLength();
String name;
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("A1");
for(int i =0; i < fstNmElmntLst.getLength(); i++ )
{
Node lst = fstNmElmntLst.item(i);
if(lst.getNodeType() == Node.ELEMENT_NODE)
{
Element fsttravel = (Element) lst;
NodeList secNmElt = fsttravel.getElementsByTagName("*");
name = secNmElt.item(0).getTextContent();
System.out.println("Name : " + name);
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
String amt;
double amount;
NodeList nodeLst = doc.getElementsByTagName("B");
int coun = nodeLst.getLength();
for (int s = 0; s < nodeLst.getLength(); s++) {
Node secNode = nodeLst.item(s);
if (secNode.getNodeType() == Node.ELEMENT_NODE) {
try
{
Element amtval = (Element) secNode;
NodeList secval = amtval.getElementsByTagName("B1");
amt = secval.item(0).getTextContent();
//amount = Double.parseDouble(amt);
System.out.println("SubAmt :" + amt);
NodeList lstNmElmntLst = amtval.getElementsByTagName("B2");
amt = lstNmElmntLst.item(0).getTextContent();
System.out.println("MainAmt : " +amt);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
current output:
Hi
Hello
100
1000
I want to read the tags alternatively. then only i can able map the values. How can i read these tags alternatively. output should be like this
Hi 100
Hello 1000
Kindly help me out of it.
Thanks in advance..
I think you need to filter only tags so that your parser will fetch only tags.For this you can use XPath.This is an examples here:
http://www.roseindia.net/tutorials/xPath/java-xpath.shtml
I have a simple XML file
<requirements>
<requirement>
<name> SwitchON</name>
<id>1</id>
<text>The Light shall turn on when the Switch is on.</text>
</requirement>
<requirement>
<name>SwitchOFF</name>
<id>2</id>
<text>The Light shall turn off when the Switch is off.</text>
</requirement>
<requirement>
<name>Lightbulb</name>
<id>3</id>
<text>The Light bulb shall be connected </text>
</requirement>
<requirement>
<name>Power</name>
<id>4</id>
<text>The Light shall have the power supply</text>
</requirement>
</requirements>
I am trying to show the information in this file in a table model.
I have a method (readFromXMl) that reads the XML file and returns a table model.
public static RequirementTable readFromXMl(String fileName) {
RequirementTable T = new RequirementTable();
Requirement R = new Requirement();
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(fileName));
doc.getDocumentElement().normalize();
NodeList listOfRequirements = doc.getElementsByTagName("requirement");
int test = listOfRequirements.getLength();
System.out.println("Total no of people : " + test);
for (int i = 0; i < listOfRequirements.getLength(); i++) {
Node RequirementNode = listOfRequirements.item(i);
if (RequirementNode.getNodeType() == Node.ELEMENT_NODE) {
Element RequirementElement = (Element) RequirementNode;
NodeList IdList = RequirementElement.getElementsByTagName("id");
Element IdElement = (Element) IdList.item(0);
NodeList textIdList = IdElement.getChildNodes();
R.setId(Integer.parseInt(textIdList.item(0).getNodeValue()));
NodeList DescriptionList = RequirementElement.getElementsByTagName("text");
Element DescriptionElement = (Element) DescriptionList.item(0);
NodeList textDescriptionList = DescriptionElement.getChildNodes();
R.setText(textDescriptionList.item(0).toString());
NodeList NameList = RequirementElement.getElementsByTagName("name");
Element NameElement = (Element) NameList;
NodeList textNameList = NameElement.getChildNodes();
if (textNameList.item(0).toString().equals("SwitchON")) {
T.addRequirement((SwitchOnReq)R);
} else if (textNameList.item(0).toString().equals("SwitchOFF")) {
T.addRequirement((SwitchOFFReq)R);
} else if (textNameList.item(0).toString().equals("LightBulb")) {
T.addRequirement((BulbRequirement)R);
} else if (textNameList.item(0).toString().equals("Power")) {
T.addRequirement((PowerRequirement)R);
}
}
}
} catch (SAXParseException err) {
System.out.println("** Parsing error" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId());
System.out.println(" " + err.getMessage());
} catch (SAXException e) {
Exception x = e.getException();
((x == null) ? e : x).printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
return T;
}
However in this line I am getting an error which says the the pointer is null
Element IdElement = (Element) IdList.item(0); IdElement is null!!
Instead of all the looping and other xml ugliness, let me suggest a little helper method:
private static String getNodeValue(Node n, String path)
throws XPathExpressionException {
XPath xpath = XPathFactory.newInstance().newXPath();
return (String) xpath.evaluate(path, n, XPathConstants.STRING);
}
Use like this:
for (int i = 0; i < listOfRequirements.getLength(); i++) {
Node RequirementNode = listOfRequirements.item(i);
System.out.println("name:" + getNodeValue(RequirementNode, "name"));
System.out.println("id:" + getNodeValue(RequirementNode, "id"));
System.out.println("text:" + getNodeValue(RequirementNode, "text"));
...
to get all the values and set your requirements.