androidjdom-2

parsing an android manifest file with JDOM2


hope you're fine. I have to parse an android manifest file to extract data like 'the minSdkVersion' used, after several seraches I found a code using JDOM. Display data related to "uses-sdk" was expected but When running I got a null object. Need Help Thanks

Manifest Example

<?xml version="1.0" encoding="UTF-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.android.rssfeed"
        android:versionCode="1"
        android:versionName="1.0" >

        <uses-sdk
            android:minSdkVersion="16"
            android:targetSdkVersion="19" />

        <uses-permission android:name="android.permission.INTERNET" />

     </manifest>

The code

import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.jdom2.*;
import org.jdom2.input.SAXBuilder;

public class ManifestP2 {

    static Document document;
    static Element root;
    static NeededTag tags;//Data receiver

    public static void main(String[] args){
        SAXBuilder builder = new SAXBuilder();
        try{

            document = builder.build(new File("AndroidManifest.xml"));

        }catch(Exception e){
            System.out.println(e.getMessage());
        }
        root = document.getRootElement();
        tags = new NeededTag();
        findTag();
        System.out.println(tags.usesSdk.toString());
    }

     static void findTag(){
         //get values for "uses-sdk" tag    
        Element sdk = root.getChild("uses-sdk");
        tags.usesSdk.minSdk = sdk.getAttributeValue("android:minSdkVersion");
        tags.usesSdk.targetSdk = sdk.getAttributeValue("android:targetSdkVersion");

    }
}

Solution

  • The attributes in your document are in the android namespace. Namespaces in XML add a level of complexity, that's true, but they also ensure that you can have special types of documents, like your manifest, where you can store "meta" types of information inside the same document as regular data, while still guaranteeing that there won't be any name collisions.

    That's a complicated way of saying that where you see android in your XML document, it refers to a namespace, not the attribute name.

    So, for example, where you have:

        <uses-sdk
            android:minSdkVersion="16"
            android:targetSdkVersion="19" />
    

    that really means you have your own element uses-sdk and that element has 2 attributes, one called minSdkVersion, and the other called targetSdkVersion. Those attributes are in the namespace with the URI: http://schemas.android.com/apk/res/android.

    To get those attributes off the element in JDOM, you have to ask for them by name, and in the right namespace.

    To do that, you have the code:

        Namespace ans = Namespace.getNamespace("android", "http://schemas.android.com/apk/res/android");
        String min = sdk.getAttributeValue("minSdkVersion", ans);
        String target = sdk.getAttributeValue("targetSdkVersion", ans);
    

    You declare the namespace to search for (only the URI is important when searching, the android namespace prefix is there for convenience only)