3

I have an XML document that contains strings with leading zeros. When I'm iterating the XML file with XmlResourceParser I have noticed that strings with leading zeros are modified removing the leading zeros when calling getAttributeValue. This functionality worked in the past and I have only noticed after upgrading to Android Studio 3.x. Is there something special I need to do in order for "getAttributeValue" to preserve the leading zeros?

Here is a test XML file that I'm using:

<?xml version="1.0" encoding="UTF-8"?>
<FictionalSpies>
<Property Country="Great Britain" Agency="MI6">
    <Item FullName="James Bond" AgentCode="007" />
    <Item FullName="John Wolfgramm" AgentCode="0010" />
    <Item FullName="Sam Johnston" AgentCode="0012" />
</Property>
<Property Country="United States" Agency="CONTROL">
    <Item FullName="Maxwell Smart" AgentCode="86" />
    <Item FullName="Unknown" AgentCode="99" />
    <Item FullName="The Chief" AgentCode="Q" />
</Property>
<Property Country="United States" Agency="MiB">
    <Item FullName="James Darrell Edwards III" AgentCode="J" />
    <Item FullName="Kevin Brown" AgentCode="K" />
    <Item FullName="Derrick Cunningham" AgentCode="D" />
</Property>
</FictionalSpies>

Here is the log print out for each 'spy' in the list. As you can see the first three have lost the "00" in their AgentCode. For example, James Bond should have agent code "007" and not "7".

D/XMLTest: Great Britain MI6 James Bond 7
D/XMLTest: Great Britain MI6 John Wolfgramm 10
D/XMLTest: Great Britain MI6 Sam Johnston 12
D/XMLTest: United States CONTROL Maxwell Smart 86
D/XMLTest: United States CONTROL Unknown 99
D/XMLTest: United States CONTROL The Chief Q
D/XMLTest: United States MiB James Darrell Edwards III J
D/XMLTest: United States MiB Kevin Brown K
D/XMLTest: United States MiB Derrick Cunningham D

Here is the code that is hooked up to a button press on a form and iterates the XML producing the previous log messages:

public void buttonOnClick(View v)
{
    int eventType = -1;
    String name;
    String country = null;
    String agency = null;
    String fullName = null;
    String agentCode = null;

    try
    {
        XmlResourceParser xmlRP = getResources().getXml(R.xml.test);

        while (eventType != XmlResourceParser.END_DOCUMENT)
        {
            if (eventType == XmlResourceParser.START_TAG)
            {
                name = xmlRP.getName();
                if (name.contentEquals("Property"))
                {
                    country = xmlRP.getAttributeValue(null, "Country");
                    agency = xmlRP.getAttributeValue(null, "Agency");
                } else if (name.contentEquals("Item"))
                {
                    fullName = xmlRP.getAttributeValue(null, "FullName");
                    agentCode = xmlRP.getAttributeValue(null, "AgentCode");

                    Log.d("XMLTest", country + " " + agency + " " + fullName + " " + agentCode );
                }
            }
            eventType = xmlRP.next();
        }
    } catch (XmlPullParserException e)
    {

    } catch (IOException e)
    {
    }
}
steve
  • 303
  • 1
  • 4
  • 11
  • 1
    I would think that it's actually the new aapt version that strips those during its processing. `getAttributeValue()` just blindly returns whatever value is there as a string. You could test that by temporarily disabling aapt2: https://stackoverflow.com/a/46988209. – Mike M. Dec 12 '17 at 03:12
  • Thanks Mike, that did fix it up! – steve Dec 12 '17 at 05:10
  • More like a temporary workaround, than a fix, really. That certainly seems like a bug in aapt2. I'll have to look into that later on, when I have more time. Glad it's workin' for ya at the moment, at least. – Mike M. Dec 12 '17 at 05:18
  • Update 7 months later: I have the latest version of Android Studio and still have aapt2 disabled. I'm now getting a warning message when building the app that says: "The Option 'android.enableAapt2' is deprecated and should not be used anymore." If I build with aapt2 enabled it is still removing leading zeros from the XML. Is there a more permanent workaround or fix that anyone knows of? Thank you. – steve Jul 20 '18 at 16:15
  • Ah, yeah, this thing. I completely forgot to investigate this, way back when. I'll try to remember to do it soon. The only other "workaround" that comes to mind at the moment would be to move your XML file to `raw/`. It'll be packaged without any pre-processing, and so should retain everything as is, but you'll have to change your code a little bit. – Mike M. Jul 21 '18 at 05:50
  • Hello again. Does it make sense to make this a new topic on AAPT and how it removes leading zeros from XML or would that be duplicating this topic? I have the latest 3.2 Android Studio and it still removes leading zeros from my XML and also warns that the work around of setting the gradle.properties to not use AAPT2 will be removed by the end of the year. Thank you – steve Sep 26 '18 at 20:13
  • No, it's still the same problem. If anything, you should search [the issue tracker](https://issuetracker.google.com/issues/new) to see if this has been reported yet, and open a new bug report, if not. Editing this question with your findings, or a link to your new issue, will bump it to the top of the active queue. – Mike M. Sep 26 '18 at 20:30

2 Answers2

1

This is a bug in AAPT2. It's been reported and already fixed in Android Studio 3.4 and 3.5 (see https://androidstudio.googleblog.com/2019/01/android-studio-35-canary-2-available.html).

You need to upgrade the Android Gradle Plugin (AGP), too (as seen here: https://stackoverflow.com/a/35272475)

With the following build.gradle entry the AAPT2 behavior can be altered to keep leading zeros:

android {
    aaptOptions {
        additionalParameters "--keep-raw-values"
    }
}

Please note that this might increases your APK size.

timbru31
  • 365
  • 2
  • 21
0

XmlResourceParser provide all data types return value, you are getting int Agencycode from parser value. so instead of getAttributeValue() use getAttributeIntValue("namespace", "attribute",0) just replace this

agentCode = xmlRP.getAttributeValue(null, "AgentCode");

To

agentCode =xmlRP.getAttributeIntValue(null, "AgentCode",0);

Happy coding!!

Hemant Parmar
  • 3,924
  • 7
  • 25
  • 49
  • Hi Hemant. I tried your suggestion but agentCode is a String and I don't want to convert it to an 'int' as that will lose the leading zeros as well. Thanks for the suggestion! – steve Dec 12 '17 at 05:15