4

im trying to build an app to read this feed: http://loc.grupolusofona.pt/index.php/?format=feed

Its working just fine, except for the fact that when it reaches the element, it just skips it, leaving it blank.

Heres 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 the 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 for what i am doing wrong ?

Thanks

3 Answers 3

2

The problem, I think, is that the <description> tags that are returned by that site all contain <![CDATA[ sections, not text. Your code for XMLParser.getElementValue only returns values for TEXT nodes. Change this:

if( child.getNodeType() == Node.TEXT_NODE  ){
    return child.getNodeValue();
}

to:

if( child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_NODE ){
    return child.getNodeValue();
}
Sign up to request clarification or add additional context in comments.

Comments

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 "";
}

you are using this code which give null while parsing description.

I try your code and to get the content of description.

I use

child.getTextContent()

and it give me the 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 description as well..,. Try it..,.

Comments

0

The description tag contains a CDATA element. Therefore it's not a text node so your check for

if( child.getNodeType() == Node.TEXT_NODE  )

will be false for those nodes. The child is most likely a CDATA_SECTION_NODE. It's also possible that the node has multiple children (text nodes if there is text outside the CDATA including whitespace) and you'll need to handle selecting the right child in that case.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.