0

I'm trying to traverse a nested XML string in Android that looks like this:

  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <Results>
    <Result>
      <Questions>
         <Question>Where can I get the local variable</Question>
         <Answer>In the local method</Answer>
         <AverageRating>3.0</AverageRating>
      </Questions>
      <Keywords>
         <Keyword>Methods</Keyword>
         <Keyword>Returns</Keyword>
         <Keyword>Void</Keyword>
      </Keywords>
    </Result>
  <Result>
      <Questions>
         <Question>How can I do a nested for loop</Question>
         <Answer>Easy</Answer>
         <AverageRating>2.5</AverageRating>
      </Questions>
      <Keywords>
         <Keyword>Methods</Keyword>
         <Keyword>Returns</Keyword>
         <Keyword>Void</Keyword>
         <Keyword>Methods</Keyword>
         <Keyword>Returns</Keyword>
       </Keywords>
   </Result>

with the following Android code:

     try 
     {
       //Creates the document
       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       DocumentBuilder builder = factory.newDocumentBuilder();
       Document document = builder.parse(new InputSource(new StringReader(serverResult)));  

    //optional, but recommended
    //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
    document.getDocumentElement().normalize();

    //Look at root node's type (e.g. <query> or <login> or <add>)
    String rootNode = document.getDocumentElement().getNodeName().toString();

     if (rootNode.equals("Results"))
     {
        String Question = "";
        String Answer = "";
        String AverageRating = "";
        float rating = 0;
        String keyword = "";

         NodeList nList = document.getElementsByTagName("Result");
         for (int i = 0; i < nList.getLength(); i++) 
         {
         Node nodes = nList.item(i);
         if (nodes.getNodeType() == Node.ELEMENT_NODE) 
         {
             Element element = (Element) nodes;                             
             NodeList list = document.getElementsByTagName("Questions");

             for (int value = 0; value < list.getLength(); value++) 
             {   
               Node node = list.item(value);

                if (node.getNodeType() == Node.ELEMENT_NODE) 
                {
                   Element eElement = (Element) node;                               
                   Question = getValue("Question", eElement);
                   Answer = getValue("Answer", eElement);
                   AverageRating = getValue("AverageRating", eElement);
                   rating = Float.parseFloat(AverageRating);
                }
             }
         }

        NodeList keywordNode = document.getElementsByTagName("Keywords");
        String keywords = "";
        for (int y = 0; y < keywordNode.getLength(); y++) 
        {
            Node node = keywordNode.item(y);

            if (node.getNodeType() == Node.ELEMENT_NODE) 
            {
                Element element = (Element) node;
                NodeList ModList = document.getElementsByTagName("Keyword");
                int count = ModList.getLength();
                for (int b = 0; b < count; b++)
                  {

           keyword = element.getElementsByTagName("Keyword").item(b).getTextContent();
           keywords = keywords + keyword + "\n"; 
                  }
            }
    items.add(new Question(Question, Answer, rating, keywords));
    }                               
 }
 }
  }
catch (Exception e)
{
String s = e.getMessage();
publishProgress(s);
}

What I'm trying to achieve is for each question of each respective results in the Result tag of my XML, I want to get the question (and it's details) and the respective keywords, adding each to the Question class, then repeat for the next result from Results tag. Can someone please help with my code and show me where I'm going wrong?

user1397978
  • 255
  • 1
  • 7
  • 24

2 Answers2

0

Try importing these:

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

by downloading them at this site: http://www.xmlpull.org/

Then, try a code structure like this:

    String XMLin;
    XmlPullParserFactory factory;
    String tag;
    ArrayList<Question> questions = new ArrayList<Question>();
    try {
        XMLin = readString(instream);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        XMLin = "Something went wrong";
    }
    try {
        // Set up the Class that will be parsing the xml file
        factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xpp = factory.newPullParser();
        xpp.setInput(new StringReader (XMLin));

        // Get the first event type
        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
        // While we have not reached the end of the document, check for start tags  
            if (eventType == XmlPullParser.START_TAG) {
                tag = xpp.getName();

                if (tag.equals("Questions") && eventType == XmlPullParser.START_TAG) {
                    Question question = new Question();
                    do {
                        if (tag.equals("Question")) {
                            // Add question text to question
                            eventType = xpp.next(); 
                                String text = xpp.getText(); // Text between tags
                        } else if (tag.equals("Answer")) {
                                eventType = xpp.next(); 
                                String text = xpp.getText(); // Text between tags
                        } else if (tag.equals("AvergaeRating") {
                                  eventType = xpp.next(); 
                                String text = xpp.getText(); // Text between tags
                        }
                        eventType = xpp.next();
                        if (eventType == XmlPullParser.TEXT) {
                            tag = xpp.getText();
                        } else {
                            tag = xpp.getName();
                        }
                    } while (!tag.equals("Questions"))
                    questions.add(question);
                 }
              }
            }

This is a modified example of something I used to parse through XML. Essentially, check for the tag name and event (whether it's a start tag or end tag, etc) and then perform that actions you want depending on those two values, such as add the text inbetween into a Question object or whatnot.

krodmannix
  • 845
  • 10
  • 30
0

I managed to use this code:

                try 
                {
                    //Creates the document
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    Document document = builder.parse(new InputSource(new StringReader(serverResult)));  

                    //optional, but recommended
                    //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
                    document.getDocumentElement().normalize();

                        //Look at root node's type (e.g. <query> or <login> or <add>)
                        String rootNode = document.getDocumentElement().getNodeName().toString();

                        if (rootNode.equals("Results"))
                        {
                             //Any methods which need to be called that will be used to query the database
                            //Always sending the String XML through as a parameter
                            //Look at the child node
                            String Question = "";
                            String Answer = "";
                            String AverageRating = "";
                            float rating = 0;

                            String keywords = "";
                            NodeList nList = document.getElementsByTagName("Questions");

                            System.out.println("----------------------------");

                            for (int temp = 0; temp < nList.getLength(); temp++) 
                            {
                                Node nNode = nList.item(temp);
                                System.out.println("\nCurrent Element :" + nNode.getNodeName());
                                if (nNode.getNodeType() == Node.ELEMENT_NODE) 
                                {

                                    Element eElement = (Element) nNode;

                                    Question = getValue("Question", eElement);
                                    Answer = getValue("Answer", eElement);
                                    AverageRating = getValue("AverageRating", eElement);
                                    rating = Float.parseFloat(AverageRating);

                                     NodeList List = document.getElementsByTagName("Keywords");


                                        for (int a = 0; a < List.getLength(); a++) 
                                            {

                                            Node node = List.item(temp);

                                                    if (node.getNodeType() == Node.ELEMENT_NODE) 
                                                    {
                                                        Element element = (Element) node;
                                                        String Keyword = element.getElementsByTagName("Keyword").item(0).getTextContent();
                                                        keywords = keywords + Keyword + "\n";  
                                                    }

                                            }
                                }
                                items.add(new Question(Question, Answer, rating, keywords));
                            }

                        }
                }
                catch (IOException e) {
                    e.printStackTrace();
                } catch (ParserConfigurationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (SAXException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

which then get's each individual question (and all their information - question, answer, rating) and well as the respective keywords for that question and add to a Question object, then loop back. I wasn't putting the keywords XML parse within the questions for loop. Hopefully this helps someone who is struggling with similar problems.

user1397978
  • 255
  • 1
  • 7
  • 24