简体   繁体   English

使用Java解析XML文件以获取名称列表

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

I am currently working on an Android app and that means learning Java. 我目前正在开发Android应用程序,这意味着学习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. 我已经玩了几年Python,但现在我已经决定加强Android手机了。 The app basically displays a list of video games stored in an XML file locally. 该应用程序基本上显示本地存储在XML文件中的视频游戏列表。 Right now, the structure of the XML file is basically games>game (Multiple)>name (Plus other things not important now). 现在,XML文件的结构基本上是游戏>游戏(多个)>名称(加上现在不重要的其他东西)。 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. 另外,请记住,名称列表必须最终作为Android的字符串数组才能使用它。 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. 这是我现在拥有的功能(从教程中复制/粘贴并经过大量编辑,所以它不可读。一旦它实际工作,我将修复它。)现在listview显示为空。 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. 在您的代码中,在向游戏列表添加fstNmElmnt.toString()时,它是与游戏标记对应的元素。 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): 假设您的XML是结构化<name> Joe </ name>,那么您需要获取第一个子节点的值(而不是为Element本身调用toString()):

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: 顺便说一句,除非你在文档的其他部分有<name>标签,或者在这个阶段需要<game>元素进行其他处理,你可以使用以下(更简单的)代码:

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

Robert Massaioli's answer provides insights into using Simple. Robert Massaioli的回答提供了使用Simple的见解。

The important thing to remember is that Simple XML should be able to follow any structure that you can logically generate using classes. 需要记住的重要一点是,Simple XML应该能够遵循您可以使用类逻辑生成的任何结构。 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. 因此,您可以创建一个使用错误接口的BaseClass并应用Decorator模式,以便将所有这些传递到具体的错误类,而不需要任何实现对象需要知道它们已经给出了什么。

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; 包com.massaiolir.simple.iface;

import java.io.File; import java.io.File;

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

public class Main { public static void main(String[] args) throws Exception { Serializer serial = new 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")); 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: BaseObject.java类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

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

public class BaseObject implements Error { @Element(name = "Err", required = false, type = ConcreteError.class) private Error err; public class BaseObject实现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'. 如果它想要'Err',这就是所有应该扩展的类。

The Error interface: 错误界面:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

public interface Error { void setErrorText(String errorText); public interface Error {void setErrorText(String errorText);

String getErrorText();

} The ConcreteError class: ConcreteError类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Attribute;

public class ConcreteError implements Error { @Attribute private String text; 公共类ConcreteError实现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: Con类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

public class Con extends BaseObject { 公共类Con扩展BaseObject {

} The ConList class: ConList类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

import java.util.ArrayList; import java.util.ArrayList;

import org.simpleframework.xml.ElementList; import org.simpleframework.xml.ElementList;

public class ConList extends BaseObject { @ElementList(entry = "Con", inline = true) public ArrayList cons; 公共类ConList扩展BaseObject {@ElementList(entry =“Con”,inline = true)public ArrayList cons; } The ConRes class: ConRes类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

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

public class ConRes extends BaseObject { @Element(name = "ConList") public ConList conList; 公共类ConRes扩展BaseObject {@Element(name =“ConList”)public ConList conList; } The ResC class: ResC类:

package com.massaiolir.simple.iface; 包com.massaiolir.simple.iface;

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

@Root public class ResC extends BaseObject { @Element(name = "ConRes") public ConRes conRes; @Root公共类ResC扩展了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. 我希望这有助于你了解如何做这样的事情。

尝试使用简单 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM