XML-Android parsing - parsing the <description> tag
im trying to create an application to read this feed: http://loc.grupolusofona.pt/index.php/?format=feed
It works fine, except when it reaches an element, it just skips it, leaving it empty.
Here is what I got:
public class AndroidXMLParsingActivity extends ListActivity { // All static variables static final String URL = "http://loc.grupolusofona.pt/index.php/?format=feed"; // XML node keys static final String KEY_ITEM = "item"; // parent node static final String KEY_ID = "id"; static final String KEY_TITLE = "title"; static final String KEY_DESC = "description"; static final String KEY_LINK = "link"; static final String KEY_PUBDATE = "pubDate"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>(); XMLParser parser = new XMLParser(); String xml = parser.getXmlFromUrl(URL); // getting 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 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_ID, parser.getValue(e, KEY_ID)); map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); map.put(KEY_DESC, parser.getValue(e, KEY_DESC)); map.put(KEY_LINK, parser.getValue(e, KEY_LINK)); map.put(KEY_PUBDATE, parser.getValue(e, KEY_PUBDATE)); // adding HashList to ArrayList menuItems.add(map); } // Adding menuItems to ListView ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.list_item, new String[] { KEY_TITLE, KEY_DESC, KEY_PUBDATE, KEY_LINK }, new int[] { R.id.title, R.id.desc, R.id.pub, R.id.link}); setListAdapter(adapter); // selecting single ListView item ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // getting values from selected ListItem String title = ((TextView) view.findViewById(R.id.title)).getText().toString(); String description = ((TextView) view.findViewById(R.id.desc)).getText().toString(); String link = ((TextView) view.findViewById(R.id.link)).getText().toString(); // Starting new intent System.out.println("Title: " + title); System.out.println("Link: " + link); System.out.println("Description:" + description); Intent in = new Intent(Intent.ACTION_VIEW); in.setData(Uri.parse(link)); startActivity(in); } }); } } And XMLParser:
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)); } }
Any ideas on what I'm doing wrong?
thanks
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 ""; } you are using this code which gives null when describing parsing.
I try your code and get the contents of the description.
I use
child.getTextContent() and it gives me content.
Change your code to
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.getNodeName().equalsIgnoreCase("description")) { return child.getTextContent(); } if( child.getNodeType() == Node.TEXT_NODE ){ return child.getNodeValue(); } } } } return ""; } And you got the content of the description as well.,. Try ..,.
The problem, I think, is that the <description> tags that are returned by this site contain <![CDATA[ , and not text sections. Your code for XMLParser.getElementValue returns values ββfor TEXT nodes only. Change this:
if( child.getNodeType() == Node.TEXT_NODE ){ return child.getNodeValue(); } in
if( child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_NODE ){ return child.getNodeValue(); } The description tag contains a CDATA element. Therefore it is not node text, therefore your check for
if( child.getNodeType() == Node.TEXT_NODE ) will be false for these nodes. The child is most likely CDATA_SECTION_NODE. It is also possible that node has several children (text nodes, if there is text outside of CDATA, including space), and you will need to handle the selection of the correct child in this case.