I figured out how to deal with a 'normal' XML-tree. But I receive the following string from a 3rd party server:
<CallOverview>
<Calls Count="2">
<Call CallType="GeoCall" Customer="this account" StartTime="2013-07-22 17:53:22 (UTC)" Destination="+123456789" Duration="00:00:14" Charge="0.00374" CallId="1472453365"/>
<Call CallType="GeoCall" Customer="this account" StartTime="2013-07-22 16:42:45 (UTC)" Destination="+123456789" Duration="00:00:05" Charge="0.00284" CallId="1472377565"/>
</Calls>
<MoreData>False</MoreData>
</CallOverview>
I'm retrieving a DOM-element with this method:
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
And the results with this method:
Element e = (Element) nl.item(i); //nl is a nodelist of parent nodes
public HashMap<String, String> getResults(Element item) {
HashMap<String, String> map = new HashMap<String, String>();
NodeList results = item.getElementsByTagName(KEY_RESULT);
//I run through the node list:
map.put("RESPONSE", this.getElementValue(results.item(i)));
...
return map;
}
But when I try the same for this XML, I'm not getting the desired results.
I want a List of calls with their destination, duration, cost. So basically I want the data between the "":
<Call CallType="GeoCall" Customer="this account" StartTime="2013-07-22 17:53:22 (UTC)" Destination="+123456789" Duration="00:00:14" Charge="0.00374" CallId="1472453365"/>
NodeList results = doc.getElementsByTagName("Call");
for (int i = 0; i < results.getLength(); i++) {
Element element = (Element) results.item(i);
String attribute= element.getAttribute("CallType");
String attribute2= element.getAttribute("Customer");
}
You can get attributes with name using element.getAttribute() function.
Related
I have a xml data like below:
<toplevel>
<CompleteSuggestion>
<suggestion data="madonna"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna like a prayer"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna like a virgin"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna vogue"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna la isla bonita"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna frozen"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna holiday"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna music"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna gimme all your love"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="madonna celebration"/>
</CompleteSuggestion>
</toplevel>
I am parsing this by using a XMLParser class below:
public class XMLParser {
// constructor
public XMLParser() {
}
/**
* Getting XML from URL making HTTP request
* #param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
/**
* Getting XML DOM element
* #param XML string
* */
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
/** Getting node value
* #param elem element
*/
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
Log.e("in element","element");
if (elem.hasChildNodes()){
Log.e("in child","child nodes");
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
Log.e("in for","for loop");
child = elem.getFirstChild();
if( child.getNodeType() == Node.TEXT_NODE ){
Log.e("in if condition","if cond");
return elem.getNodeValue();
}
}
}
}
return "";
}
/**
* Getting node value
* #param Element node
* #param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
}
Here is my Activity code:
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Log.e("string xml","hello"+xml);
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
Log.e("no. of items",""+i);
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
Log.e("names","hi"+parser.getValue(e, KEY_NAME));
menuItems.add(map);
}
I observed that my getElementValue( Node elem ) in XmLParser is always returning empty String. I think I need to change this method. I tried by changing some of the statements but didn't find any solution.
how to parser the following XML using DOM PARSER
<Result>
<Status>OK</Status>
<All_BookDetails>
<BookAuthor>Mohammadi Reyshahri</BookAuthor>
<BookRating>0</BookRating>
<BookDescription>Islamic belief and ideology</BookDescription>
<DatePublished>May 1 1992 12:00AM</DatePublished>
<BookTitle>Are You Free or Slave</BookTitle>
<BookID>171</BookID>
<BookCode>EN171</BookCode>
<BookImage>1.jpg</BookImage>
<TotalPages>164</TotalPages>
</All_BookDetails>
</Result>
i want to get the values of BookAuthor, BookRating, BookDescription,DatePublished, BookTitle, BookID, BookCode, BookImage TotalPages
how can i do this. I tried to parse the above XML selecting All_BookDetails as parent node but nodelist returning me the 0 in length
thanks
Getting XML DOM element
public Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setCoalescing(true);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
return null;
} catch (SAXException e) {
return null;
} catch (IOException e) {
return null;
}
return doc;
}
then I tried this and its worked
Document doc = parser.getDomElement(XMLString);
NodeList nl = doc.getElementsByTagName("All_BookDetails");
progressDialog.setCancelable(true);
Element e = (Element) nl.item(0);
BookRating = (Integer.valueOf(parser.getValue(e,
"BookAuthor")));
BookTitle = parser.getValue(e, "BookTitle");
BookAuthor = parser.getValue(e, "BookAuthor");
BookPublishDate = parser.getValue(e, "DatePublished");
BookDescription = parser.getValue(e, "BookDescription");
bookID = parser.getValue(e, "BookID");
bookCode = parser.getValue(e, "BookID");
bookPageCount = parser.getValue(e, "TotalPages");
I want to access particular attributes from xml like in this example there are 2 image tag but 2 different attributes size small and size medium so how can i access medium
<image size="small">http://userserve-ak.last.fm/serve/34/62210477.png</image><image size="medium">http://userserve-ak.last.fm/serve/64/62210477.png</image>
I tried this it works on lower android version but it wont work on 4.0
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
try {
expr = xpath.compile("//image[#size=\"large\"]");
nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
here is Full code
public class loadSomeStuff extends AsyncTask<Void, Void, String>
{
XPathExpression expr;
NodeList nl;
int i;
String name="test";
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
final String KEY_NAME = "name";
final String KEY_IMAGE ="image";
//final String KEY_COST = "cost";
//final String KEY_DESC = "description";
String URL = "http://ws.audioscrobbler.com/2.0/?method=artist.search&artist=enrique_iglesias&api_key=b25b959554ed76058ac220b7b2e0a026&limit=" + 1 + "&page=" + 1;
XmlParser parser = new XmlParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
//XPathFactory xPathfactory = XPathFactory.newInstance();
//XPath xpath = xPathfactory.newXPath();
//try {
// expr = xpath.compile("//image[#size=\"large\"]");
//nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
NodeList nl = doc.getElementsByTagName("artist");
for (i = 0; i < nl.getLength(); i++)
{
Element e = (Element) nl.item(i);
name = parser.getValue(e, KEY_NAME);// name child value
image = parser.getValue(e, KEY_IMAGE);
System.out.print(image);
Log.v(image, "image url");
return image;
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
URL thumb_u;
try {
thumb_u = new URL(result);
Drawable thumb_d = Drawable.createFromStream(thumb_u.openStream(), "src");
Toast toast = Toast.makeText(myActionbar.this, image, Toast.LENGTH_LONG);
toast.show();
icon.setImageDrawable(thumb_d);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
here is My Xmlparserfile in which my getvalue and get elements are defined
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if( child.getNodeType() == Node.TEXT_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
}
}
Try this:
XMLParser parser = new XMLParser();
String URL = "http://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums&artist=akon&api_key=your_api_key";
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("album");
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
Log.e("name", parser.getValue(e, "name"));
NodeList k = e.getElementsByTagName("image");
for (int j = 0; j < k.getLength(); j++) {
Element e1 = (Element) k.item(j);
if(e1.getAttribute("size").equals("large"))
Log.e("ImageURL", parser.getValue(e1, "image"));
}
}
I've seen quite a few posts about this, but actually I did not get any to work. I am building a simple TV guide android application. I simply Use RSS from a tvprofil.net to show whats on TV today. The problem is, I do not know how to Parse CDATA in XML. I am using some standard parser with DOM... at least I think so..
This is a bit of XML:
.
.
.
<item>
<title>RTS1 14.08.2012</title>
<pubDate>Tue, 14 Aug 2012 06:00:00</pubDate>
<content:encoded><![CDATA[06:00 Vesti<br>06:05 Jutarnji program<br>08:00 Dnevnik
<br>8:15 Jutarnji Program<br>09:00 Vesti ... ]]></content:encoded>
</item>
.
.
.
now, this is my main app:
public class Main extends ListActivity {
// All static variables
static final String URL = "http://tvprofil.net/rss/feed/channel-group-2.xml";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_NAME = "title";
static final String KEY_DATE = "pubDate";
static final String KEY_DESC = "content:encoded";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<HashMap<String,String>> menuItems = new ArrayList<HashMap<String,String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); //get XML
Document doc = parser.getDomElement(xml); // get DOM elem.
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
//loop
for (int i=0; i< nl.getLength(); i++){
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
//add to map
map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
map.put(KEY_DATE, parser.getValue(e, KEY_DATE));
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
// hash => list
menuItems.add(map);
}
ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.list_item,
new String[]{KEY_NAME, KEY_DESC, KEY_DATE}, new int[]{
R.id.name, R.id.description, R.id.date
});
setListAdapter(adapter);
//singleView
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String name = ((TextView)view.findViewById(R.id.name)).getText().toString();
String date = ((TextView)view.findViewById(R.id.date)).getText().toString();
String description = ((TextView)view.findViewById(R.id.description)).getText().toString();
//intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(KEY_NAME, name);
in.putExtra(KEY_DATE, date);
in.putExtra(KEY_DESC, description);
startActivity(in);
}
});
}
}
and the parser class:
public class XMLParser {
// constructor
public XMLParser() {
}
/**
* Getting XML from URL making HTTP request
* #param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
/**
* Getting XML DOM element
* #param XML string
* */
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
/** Getting node value
* #param elem element
*/
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if( child.getNodeType() == Node.TEXT_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
}
/**
* Getting node value
* #param Element node
* #param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
}
there is one more class for Single menu item.. but I think it's irrelevant in this case.
Now, I'd just like to see no HTML tags after parsing it and dealing with CDATA...
Anyone got idea about this one?
Add this
dbf.setCoalescing(true);
where dbf is
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
First add this method
public String getCharacterDataFromElement(Element e, String str) {
NodeList n = e.getElementsByTagName(str);
Element e1=(Element) n.item(0);
Node child = e1.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "";
}
Call the above method as so-
map.put(KEY_DESC, parser.getCharacterDataFromElement(e, KEY_DESC));
This should get you the CDATA in String format. HOpe this helps
getTextContent.
This attribute returns the text content of this node and its
descendants
getNodeValue()
The value of this node, depending on its type;
usually you shouled use getTextContent.
zg_spring's answer worked perfectly for me when I needed to extract image URLs from CDATA in a set of "description" xml elements:
//Get the content of all "item" elements
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
NodeList nlDetails = doc.getElementsByTagName("item");
//Loop through elements and extract content of "description" elements
for(int k = 0; k < numDetails; k++) {
Element nDetails = (Element)nlDetails.item(k);
NodeList nlCoverURL = nDetails.getElementsByTagName("description");
Node nCoverURL = nlCoverURL.item(0);
String sCoverURL = nCoverURL.getTextContent();
//Isolate the relevant part of the String and load it into an ArrayList
String[] descriptionContent = sCoverURL.split("\"");
String s = descriptionContent[11]
alImages.add(s);
}
I am trying to parse an XML file as below
<Subject>
<chapter>
<Question>abc</Question>
<answer>avksn</answer>
</chapter>
<chapter>
<Question>def</Question>
<answer>avksn</answer>
</chapter>
<chapter>
<Question>ccsv</Question>
<answer>avksn</answer>
</chapter>
</Subject>
in this i am able to count the number of chapter. the number of chapter is equal to number of question and answer. i have also placed a button named as ok in my layout.
now i want to display the first question and after clicking ok i want to display the second question and it goes till the end. When i reached the last question i want to move to a new activity.
how to perform this, pls help me
Read the xml into a InputStream and then:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse([the InpuTstream]);
Then you can use doc like:
if(doc.getElementsByTagName("GeometryCollection").getLength()>0){
org.w3c.dom.Node parent_node = doc.getElementsByTagName("GeometryCollection").item(0);
NodeList nl = parent_node.getChildNodes();
for(int i = 0;i<nl.getLength();i++){
...
Read the XML into a document ( v = the xml string )
public Document XMLfromString(){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(v));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
System.out.println("Wrong XML file structure: " + e.getMessage());
return null;
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
Then get the element like so:
/** Returns element value
* #param elem element (it is XML tag)
* #return Element value otherwise empty String
*/
public final static String getElementValue( Node elem ) {
Node kid;
if( elem != null){
if (elem.hasChildNodes()){
for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
if( kid.getNodeType() == Node.TEXT_NODE ){
return kid.getNodeValue();
}
}
}
}
return "";
}
How to use:
Document doc = x.XMLfromString();
NodeList nodes = doc.getElementsByTagName("result");
for (int i = 0; i < nodes.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element)nodes.item(i);
map.put("id", x.getValue(e, "orgid"));
map.put("bedrijf", x.getValue(e, "naam"));
map.put("plaats", x.getValue(e, "plaats"));
mylist.add(map);
}