I'm using dom4j to parse AndroidManifestFile.xml. However I found that it treats "android:xxx" attribute strangely.
For example:
<receiver android:name="ProcessOutgoingCallTest" android:exported="false"
android:enabled="false">
<intent-filter android:priority="1">
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
The return value e.attributeValue("android:exported")
will be null
however using e.attributeValue("exported")
will obtain the correct string (but I don't like this way since it may match more than expected). Meanwhile, e.attributeValue(new QName("android:exported"))
will still be a null string.
What's the correct way to get the attribute
The android:
is nothing more than a namespace
in XML.
If there is only one possible namespace, it is ok to write e.attributeValue("exported")
.
QName represents a qualified name value of an XML element or attribute. It consists of a local name and a Namespace instance
QName(String name)
QName(String name, Namespace namespace)
QName(String name, Namespace namespace, String qualifiedName)
thus, new QName("android:exported")
is wrong, and the correct form is
new QName("exported", new Namespace("android", "http://schemas.android.com/apk/res/android"))
If you miss its namespace here, you take it as NO_NAMESPACE
for default.
public QName(String name) {
this(name, Namespace.NO_NAMESPACE);
}
Example:
Element root = document.getRootElement();
Namespace namespace = new Namespace("android", "http://schemas.android.com/apk/res/android");
for(Iterator i = root.elementIterator("receiver"); i.hasNext();)
{
Element e = (Element)i.next();
System.out.println(e.attributeValue("exported"));
System.out.println(e.attributeValue(new QName("exported", namespace)));
}