0

I've just started using DOM and wanted to parse an Android XML layout file e.g.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" 
android:padding="30dip">

<LinearLayout
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center" >


    <EditText android:id="@+id/entry1" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:background="@android:drawable/editbox_background"/>

    <EditText android:id="@+id/entry2" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:background="@android:drawable/editbox_background"/>


    <EditText android:id="@+id/entry3" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:background="@android:drawable/editbox_background"/>

</LinearLayout>
</LinearLayout>

And get output like this (only on the ID's of the EditText's):

ID: @+id/entry1
ID: @+id/entry2
ID: @+id/entry3

Is there a way to do this? Could someone please point me to a tutorial or give me some ideas?

Current code:

final String ANDROID_ID = "android:id";

            try {
                File fXmlFile = new File("res/layout/page1.xml");
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory
                        .newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(fXmlFile);
                doc.getDocumentElement().normalize();

                NodeList nList = doc.getElementsByTagName("Button");

                for (int temp = 0; temp < nList.getLength(); temp++) {
                    Node nNode = nList.item(temp);
                    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                        Element eElement = (Element) nNode;

                        if (eElement.hasAttribute(ANDROID_ID))
                            System.out.println("ID: "
                                    + eElement.getAttribute(ANDROID_ID));
                    }
                }
            } 

            catch (Exception e) {
                System.out.println("Catch");


  e.printStackTrace();
        }

Thanks!

litterbugkid
  • 3,534
  • 7
  • 36
  • 54
  • Do you want to parse the layout files within Android, or externally? If externally, what platform/language/etc do you prefer to use? There are lots of XML tools out there, so there's no point in giving a Java solution, for example, if your only tool is Visual Basic... – Dalbergia Nov 10 '11 at 17:22
  • You can easily retrieve the desired data from the XML using [XPath](http://www.w3schools.com/xpath/default.asp) expressions, if any XPath interpreter is available on your platform (e.g. in [Java](http://download.oracle.com/javase/1,5.0/docs/api/javax/xml/xpath/package-summary.html)). – JimmyB Nov 10 '11 at 17:52

1 Answers1

0

If you want to use Java DOM, try doing something like this

    final String ANDROID_ID = "android:id";

    try {

        File fXmlFile = new File("res/layout/parse.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory
                .newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(fXmlFile);
        doc.getDocumentElement().normalize();

        NodeList nList = doc.getElementsByTagName("*");

        for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                Element eElement = (Element) nNode;

                if (eElement.hasAttribute(ANDROID_ID))
                    System.out.println("ID: "
                            + eElement.getAttribute(ANDROID_ID));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

There are probably much more efficient ways to do this (like using SAX instead), but it works.

skynet
  • 9,898
  • 5
  • 43
  • 52
  • For some reason your method works when I access the xml file on my local drive but if I use the res/layout/page1.xml path it can't seem to find it and goes into the catch block. Do you know a way of fixing this? I've added my code into my first post. – litterbugkid Nov 21 '11 at 11:32
  • You cannot simply reference that path. Try using `InputStream is = getResources().openRawResource(R.layout.page1);` instead. – skynet Nov 21 '11 at 22:44
  • That works when I put it in the raw folder. This way getting the id attributes from the xml page doesn't come out in binary. – litterbugkid Nov 24 '11 at 16:17