0
votes

I have a problem with using getElementsByTagName("*")

Documentaion says

-getElementsByTagName NodeList getElementsByTagName(String name)

Returns a NodeList of all descendant Elements with a given tag name, in document order.

Parameters: name - The name of the tag to match on. The special value "*" matches all tags. Returns: A list of matching Element nodes.

while it returns only the FIRST element Node in xml like :

<ui>
<entry>
<img>
<icon>...</icon>
<action>image</action>
<data/>
<xpos>2</xpos>
<ypos>47</ypos>
</img>
<btn>
<icon>
http://epic-demo.com/testxml/images/200214050213call.png
</icon>
<action>call</action>
<data>19019</data>
<xpos>128</xpos>
<ypos>61</ypos>
</btn>
<btn>
<icon>
http://epic-demo.com/testxml/images/200214050237map.png
</icon>
<action>url</action>
<data>http://goo.gl/SPBvt</data>
<xpos>236</xpos>
<ypos>165</ypos>
</btn>
<btn>
<icon>
http://epic-demo.com/testxml/images/200214050221video.png
</icon>
<action>video</action>
<data>tMVE2MaLe8I</data>
<xpos>14</xpos>
<ypos>173</ypos>
</btn>
</entry>
</ui>

Why it not return all elements ?!

Parser

public class XMLDOMParser {
    //Returns the entire XML document
    public Document getDocument(InputStream inputStream) {
        Document document = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = factory.newDocumentBuilder();
            InputSource inputSource = new InputSource(inputStream);
            document = db.parse(inputSource);
        } 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 document;
    }
 
    
    public String getValue(Element item, String name) {
        NodeList nodes = item.getElementsByTagName(name);
        return this.getTextNodeValue(nodes.item(0));
    }
 
    private final String getTextNodeValue(Node node) {
        Node child;
        if (node != null) {
            if (node.hasChildNodes()) {
                child = node.getFirstChild();
                while(child != null) {
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        return child.getNodeValue();
                    }
                    child = child.getNextSibling();
                }
            }
        }
        return "";
    }
}

Code

private ArrayList<UIElement> loadXmlFromNetwork(String urlString)
            throws XmlPullParserException, IOException {

        InputStream stream = null;

        XMLDOMParser parser = new XMLDOMParser();
        stream = downloadUrl(urlString);
        Document doc = parser.getDocument(stream);
        
        ArrayList<UIElement> UI_array = new ArrayList<UIElement>();
        
        // Get elements by name btn
        NodeList btns_entries = doc.getElementsByTagName("*");
                
        for (int j = 0; j < btns_entries.getLength(); j++) {

            Element e = (Element) btns_entries.item(j);
            
            UIElement btn = new UIElement();

            btn.setIcon(parser.getValue(e, NODE_ICON));
            btn.setAction(parser.getValue(e, NODE_ACTION));
            btn.setData(parser.getValue(e, NODE_DATA));
            btn.setXpos(parser.getValue(e, NODE_XPOS));
            btn.setYpos(parser.getValue(e, NODE_YPOS));

            UI_array.add(btn);          

        }
        
        return UI_array;

    }
1
so whats your question? - tyczj
Why it not return all elements like documentation said ?! - Shymaa Othman

1 Answers

2
votes

I assume it returns <ui> element only? If so - that's expected. Root of the document contains only one node - <ui>. But <ui> element has a lot of children. getElementsByTagName() is not recursive. So if you try to get <ui> node first and then get all nodes out of this node - you will get what you expect.

EDIT:

I also noticed that you have another top-level element - entry. You might need to get that element too and then get all child nodes in entry

EDIT2:

I tried to use your code and your xml and it works for me - I get all the nodes in XML. Is there any chance your XML is not what you expect it to be?

private void parse()
{
   String xml =  "<ui>\n" +
            "  <entry>\n" +
            "    <img>\n" +
            "      <icon>...</icon>\n" +
            "      <action>image</action>\n" +
            "      <data />\n" +
            "      <xpos>2</xpos>\n" +
            "      <ypos>47</ypos>\n" +
            "    </img>\n" +
            "    <btn>\n" +
            "      <icon>http://epic-demo.com/testxml/images/200214050213call.png</icon>\n" +
            "      <action>call</action>\n" +
            "      <data>19019</data>\n" +
            "      <xpos>128</xpos>\n" +
            "      <ypos>61</ypos>\n" +
            "    </btn>\n" +
            "    <btn>\n" +
            "      <icon>http://epic-demo.com/testxml/images/200214050237map.png</icon>\n" +
            "      <action>url</action>\n" +
            "      <data>http://goo.gl/SPBvt</data>\n" +
            "      <xpos>236</xpos>\n" +
            "      <ypos>165</ypos>\n" +
            "    </btn>\n" +
            "    <btn>\n" +
            "      <icon>http://epic-demo.com/testxml/images/200214050221video.png</icon>\n" +
            "      <action>video</action>\n" +
            "      <data>tMVE2MaLe8I</data>\n" +
            "      <xpos>14</xpos>\n" +
            "      <ypos>173</ypos>\n" +
            "    </btn>\n" +
            "  </entry>\n" +
            "</ui>\n";



    Document doc = getDocument(xml);

    // Get elements by name btn
    NodeList btns_entries = doc.getElementsByTagName("*");

    for (int j = 0; j < btns_entries.getLength(); j++) {

        Element e = (Element) btns_entries.item(j);
        Log.d("log", e.getTagName());
    }
}

public Document getDocument(String xml) {
    Document document = null;
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
        DocumentBuilder db = factory.newDocumentBuilder();
        InputSource inputSource = new InputSource(new ByteArrayInputStream(xml.getBytes("UTF-8")));
        document = db.parse(inputSource);
    } 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 document;
}

Output:

03-13 15:13:19.528    1540-1540/? D/log﹕ ui
03-13 15:13:19.528    1540-1540/? D/log﹕ entry
03-13 15:13:19.528    1540-1540/? D/log﹕ img
03-13 15:13:19.528    1540-1540/? D/log﹕ icon
03-13 15:13:19.528    1540-1540/? D/log﹕ action
03-13 15:13:19.528    1540-1540/? D/log﹕ data
03-13 15:13:19.528    1540-1540/? D/log﹕ xpos
03-13 15:13:19.528    1540-1540/? D/log﹕ ypos
03-13 15:13:19.528    1540-1540/? D/log﹕ btn
03-13 15:13:19.528    1540-1540/? D/log﹕ icon
03-13 15:13:19.528    1540-1540/? D/log﹕ action
03-13 15:13:19.528    1540-1540/? D/log﹕ data
03-13 15:13:19.528    1540-1540/? D/log﹕ xpos
03-13 15:13:19.528    1540-1540/? D/log﹕ ypos
03-13 15:13:19.528    1540-1540/? D/log﹕ btn
03-13 15:13:19.528    1540-1540/? D/log﹕ icon
03-13 15:13:19.528    1540-1540/? D/log﹕ action
03-13 15:13:19.528    1540-1540/? D/log﹕ data
03-13 15:13:19.528    1540-1540/? D/log﹕ xpos
03-13 15:13:19.528    1540-1540/? D/log﹕ ypos
03-13 15:13:19.528    1540-1540/? D/log﹕ btn
03-13 15:13:19.528    1540-1540/? D/log﹕ icon
03-13 15:13:19.528    1540-1540/? D/log﹕ action
03-13 15:13:19.528    1540-1540/? D/log﹕ data
03-13 15:13:19.528    1540-1540/? D/log﹕ xpos
03-13 15:13:19.528    1540-1540/? D/log﹕ ypos