Open XML file from res/xml in Android
Asked Answered
M

3

7

I created a Java application which opens an xml file that looks something like this:

<AnimalTree>
  <animal>
    <mammal>canine</mammal>
    <color>blue</color>
  </animal>
  <!-- ... -->
</AnimalTree>

And I can open it using:

File fXmlFile = getResources.getXml("res/xml/data.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList animalNodes = doc.getElementsByTagName("animal");

Then I can simply create a node, push the object into a ListArray, then do what I want with the objects as I loop through the ListArray.

for (int temp = 0; temp < animalNodes.getLength(); temp++) {
Node nNode = animalNodes.item(temp);     
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
question thisAnimal = new animal();
thisAnimal.mammal = getTagValue("mammal",eElement);
// ...

Plain and simple! Now only, in Android I cannot simply read the file "res/xml/data.xml" because "File();" requires a String not an integer (id). This is where I am lost. Is there some way I can make "File();" open the file, or is this impossible without using SAXparser or XPP? (both of which I really cannot understand, no matter how hard I try.)
If I am forced to use those methods, can someone show me some simple code analogous to my example?

Margaret answered 1/12, 2010 at 21:26 Comment(0)
M
9

If it's in the resource tree, it'll get an ID assigned to it, so you can open a stream to it with the openRawResource function:

InputStream is = context.getResources().openRawResource(R.xml.data);

As for working with XML in Android, this link on ibm.com is incredibly thorough.

See Listing 9. DOM-based implementation of feed parser in that link.

Once you have the input stream (above) you can pass it to an instance of DocumentBuilder:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("TheTagYouWant");

Keep in mind, I haven't done this personally -- I'm assuming the code provided by IBM works.

Mitsue answered 1/12, 2010 at 21:34 Comment(7)
I don't get it? Do i then change is to a string and put that into "File();" ? The IBM resource you left shows how to pull xml from online just fine. I don't understand why this is so hard? Can you create a pseudo code version of what I posted above? Thanks.Margaret
That's better and I saw that on the IBM site, but "getInputStream();" is in the BaseFeedParser class, which "implements" the FeedParser class which is not listed on the IBM site. I created the BaseFeedParser class in my code, but eclipse is throwing an error at me about FeedParser.Margaret
that site says : "However, DOM generally consumes more memory as everything is read into memory first. This can be a problem on mobile devices that run Android, but it can be satisfactory in certain use cases where the size of the XML document will never be very large. One might imply that the developers of Android guessed that SAX parsing would be much more common on Android applications, hence the extra utilities provided for it. " This is very bad. my XML is goind to have about 100 objects. The DOM method added 50 lines of code to my project, this is too impractical.Margaret
Are you using XML for local storage of data? I'd recommend SQLite in that case. It's native to the stack.Mitsue
Re: FeedParser: it's an interface: public interface FeedParser Mitsue
Also, there is code on there that uses inputstream via SAX, look for this: SAXParserFactory factory = SAXParserFactory.newInstance();Mitsue
Also note that openRawResource(R.xml.data) will currently give you a lint error in Android Studio: "Expected resource of type raw". Instead use getXml() (see BfD's answer).Hiltonhilum
A
2

I tried the approach using openRawResource and got a SAXParseException. So, instead, I used getXml to get a XmlPullParser. Then I used next() to step through the parsing events. The actual file is res/xml/dinosaurs.xml.

XmlResourceParser parser = context.getResources().getXml(R.xml.dinosaurs);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
    switch (eventType) {
        case XmlPullParser.START_DOCUMENT :
            Log.v(log_tag, "Start document");
            break;
        case XmlPullParser.START_TAG :
            Log.v(log_tag, "Start tag " + parser.getName() );
            break;
        case XmlPullParser.END_TAG :
            Log.v(log_tag, "End tag " + parser.getName() );
            break;
        case XmlPullParser.TEXT :
            Log.v(log_tag, "Text " + parser.getText() );
            break;
        default :
            Log.e(log_tag, "Unexpected eventType = " + eventType );
    }
    eventType = parser.next();
}
Athlete answered 3/3, 2017 at 16:50 Comment(0)
F
-1

Try this,

this.getResources().getString(R.xml.test); // returns you the path , in string,invoked on activity object
Fedak answered 27/2, 2014 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.