开发者

Parsing an XML file in Java to get a list of names

I am currently working on an Andr开发者_JS百科oid app and that means learning Java. I've toyed around with Python for a few years, but decided it was time to step up now that I have an android phone. The app basically displays a list of video games stored in an XML file locally. Right now, the structure of the XML file is basically games>game (Multiple)>name (Plus other things not important now). I am currently trying to get a list of the names of the games. I've looked up tutorials and info but none of it seems to be quite what I need. I want to actually understand how it works, not just have a working piece of code I can copy/paste. Also, keep in mind that the list of names has to end up as an array of strings for Android to use it. Here's the function I have right now (Copy/pasted from a tutorial and heavily edited, so it's not readable. I'll fix that once it's actually working.) Right now the listview shows up as empty. At least it's better than before and it doesn't crash anymore though...

public static String[] parse(String filename) {
      ArrayList<String> gamesList = new ArrayList<String>();

      try {
      File file = new File(filename);
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(file);
      doc.getDocumentElement().normalize();
      NodeList nodeList = doc.getElementsByTagName("game");

      for (int s = 0; s < nodeList.getLength(); s++) {

        Node fstNode = nodeList.item(s);

        //if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

          Element name = (Element) fstNode;
               Element fstElmnt = (Element) fstNode;
          NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("name");
          Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
          NodeList fstNm = fstNmElmnt.getChildNodes();

          gamesList.add(fstNmElmnt.toString());
        //}

      }
      } catch (Exception e) {
        e.printStackTrace();
      }
    String[] gamesArray;
    gamesArray = (String[]) gamesList.toArray(new String[0]);
    return gamesArray;
     }


In your code, at the point that you add fstNmElmnt.toString() to gameList, it is the Element corresponding to the tag of the game. Assuming that your XML is structured <name>Joe</name>, then you need to get the value of the first child (instead of calling toString() for the Element itself):

gamesList.add(fstNmElmnt.getFirstChild().getNodeValue());

By the way, unless you have <name> tags in other parts of your document, or need the <game> element for other processing at this stage, you can use the following (much simpler) code:

NodeList nodeList = doc.getElementsByTagName("name");
for (int s = 0; s < nodeList.getLength(); ++s) {
    gamesList.add(nodeList.item(s).getFirstChild().getNodeValue());
}


Try using Simple :)


Robert Massaioli's answer provides insights into using Simple.

The important thing to remember is that Simple XML should be able to follow any structure that you can logically generate using classes. So you could just create a BaseClass that uses an error interface and applies the Decorator pattern so that it passes all of that through to a concrete error class without any of the implementing objects needing to know what they have been given.

That probably made no sense. How about I just show you...okay...I just went away and implemented exactly what I was thinking and here are the results (full code link):

The Main File:

package com.massaiolir.simple.iface;

import java.io.File;

import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister;

public class Main { public static void main(String[] args) throws Exception { Serializer serial = new Persister(); ResC resc = serial.read(ResC.class, new File("data/testdata.xml"));

    System.out.println(" == Printing out all of the error text. == ");
    System.out.println(resc.getErrorText());
    System.out.println(resc.conRes.getErrorText());
    System.out.println(resc.conRes.conList.getErrorText());
    for (Con con : resc.conRes.conList.cons) {
        System.out.println(con.getErrorText());
    }
    System.out.println(" == Finished printing out all of the error text. == ");
}

} It just runs simple and displays the results.

The BaseObject.java class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class BaseObject implements Error { @Element(name = "Err", required = false, type = ConcreteError.class) private Error err;

@Override
public String getErrorText() {
    return err.getErrorText();
}

@Override
public void setErrorText(String errorText) {
    err.setErrorText(errorText);
}

} This is the class that everything should extend if it wants 'Err'.

The Error interface:

package com.massaiolir.simple.iface;

public interface Error { void setErrorText(String errorText);

String getErrorText();

} The ConcreteError class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Attribute;

public class ConcreteError implements Error { @Attribute private String text;

@Override
public String getErrorText() {
    return text;
}

@Override
public void setErrorText(String errorText) {
    this.text = errorText;
}

} The actual implementing classes are after this point. You will see that they are rather trivial because the real work is being handled in the classes above.

The Con class:

package com.massaiolir.simple.iface;

public class Con extends BaseObject {

} The ConList class:

package com.massaiolir.simple.iface;

import java.util.ArrayList;

import org.simpleframework.xml.ElementList;

public class ConList extends BaseObject { @ElementList(entry = "Con", inline = true) public ArrayList cons; } The ConRes class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class ConRes extends BaseObject { @Element(name = "ConList") public ConList conList; } The ResC class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element; import org.simpleframework.xml.Root;

@Root public class ResC extends BaseObject { @Element(name = "ConRes") public ConRes conRes; } And that is all that there is to it. Pretty simple right. I was able to bang that all out in ten minutes. It actually took me longer to write this response than it took me to write the code that I am giving you. If you do not understand anything about the code that I have just written then please let me know. I hope this helps you to understand how you might go about doing something like this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜