Home » Android » android – Java parse xml with undeclared namespace

android – Java parse xml with undeclared namespace

Posted by: admin June 15, 2020 Leave a comment

Questions:

Each time our new android app released, I need to update app info on our website. So I try to update the app info automatically, by read the AndroidManifest.xml in the apk when uploaded to server.

I use AXMLResource and jdom2 to get the AndroidManifest.xml and parse it.

final Namespace NS = Namespace.getNamespace("http://schemas.android.com/apk/res/android");

zipFile = new ZipFile(apkPath);
ZipEntry zipEntry = new ZipEntry("AndroidManifest.xml");
inputStream = zipFile.getInputStream(zipEntry);
AXMLResource axmlResource = new AXMLResource();
axmlResource.read(inputStream);

SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(new ByteArrayInputStream(axmlResource.toXML().toString().getBytes("UTF-8")));
Element root = document.getRootElement();
System.out.println(root.getAttributeValue("versionCode",NS));
System.out.println(root.getAttributeValue("versionName",NS));

But I always get,

The prefix “data” for attribute “data:versionCode” associated
with an element type “manifest” is not bound

And I print the AndroidManifest.xml,and found the data namespace is unclared.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    data:versionCode="344"
    data:versionName="3.2.8"

When I check android studio doc and found there use declared namespace.

Then I think this may be caused by our app developers’s Irregularities.

But when I think further, why app with AndroidManifest.xml with undeclared namespace can released, then I download some apks like facebook,youtube,centos,baidu disk and alipay, and found only centos doesn’t use undeclared namespace.

For com.google.android.youtube.apk

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    http:versionCode="1425572340"
    http:versionName="14.25.57"

The prefix “http” for attribute “http:versionCode” associated
with an element type “manifest” is not bound

For com.facebook.katana-225.0.0.47.118.apk

<?xml version="1.0" encoding="utf-8"?>
<manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        manifest:versionCode="158425934"
        manifest:versionName="225.0.0.47.118"

The prefix “manifest” for attribute “manifest:versionCode” associated
with an element type “manifest” is not bound

So here is comman to use undeclased namespace in AndroidManifest.xml,but how can I pase it?

How to&Answers:

Technically your file is well-formed XML but not namespace-well-formed XML. The vast majority of modern XML tools will only handle (or produce) XML that is namespace-well-formed. But if you can find an XML parser that still handles XML that is not namespace-well-formed, then you can use this to “repair” your XML in some way that meets your needs (for example, you could replace manifest:versionCode by manifest-versionCode).

However, rather than repairing the XML in this way, it would be much better to create namespace-well-formed XML in the first place, so you’re not constrained in your choice of tools.

Answer:

Your problem is not with namespacing. It’s with prefixing. Try changing:

final Namespace NS = Namespace.getNamespace("http://schemas.android.com/apk/res/android");

to this:

final Namespace NS = Namespace.getNamespace("data", "http://schemas.android.com/apk/res/android");

Not having seen the associated schema, I can’t tell if the namespaced schema contains a matching attribute descriptor on the manifest element. I don’t know if some of the classes do transparent schema validation. You don’t seem to be doing it explicitly in your code so this may be moot.

Somewhere in the data that you receive from these sources, they should tell you what the prefix is that they’re using (e.g., “data,” “manifest,” “http,” etc.) in their definition. That’ll save you having to hard-code in the, “data,” prefix.