如何将XML读入Java中的POJO列表?

时间:2017-12-08 09:50:45

标签: java xml arraylist

我是XML的新手,我试图读取XML页面并将其内容存储在arraylist中。

到目前为止,我似乎能够让arraylist充满第一个内容,就像我尝试了一个isEmpty一样,它返回false。所以肯定包含一些东西。 但是,当我尝试调用覆盖的tostring方法,或者甚至尝试调用任何单独的类别时,它只返回空?

任何人都可以帮忙吗?

继承人正在使用的代码:

package test;

import java.io.File;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;

public class xmlmx {

   public static void main(String[] args) {
      ArrayList<Anime> list = new ArrayList<Anime>();
      try {
         File inputFile = new File("c:\\code\\ad\\XMLDB.xml");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();
         System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
         NodeList nList = doc.getElementsByTagName("Anime");
         System.out.println("----------------------------");

         for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            System.out.println("\nCurrent Element :" + nNode.getNodeName());

            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               list.add(new Anime(eElement.getAttribute("ID"),
                                  eElement.getAttribute("name"),
                                  eElement.getAttribute("altname"),
                                  eElement.getAttribute("seasons"),
                                  eElement.getAttribute("episodes"),
                                  eElement.getAttribute("status"),
                                  eElement.getAttribute("DS"),
                                  eElement.getAttribute("have"),
                                  eElement.getAttribute("left"),
                                  eElement.getAttribute("plot"),
                                  eElement.getAttribute("connect"),
                                  eElement.getAttribute("image")));
               System.out.println(list.get(0).toString());
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

arraylist是动漫类型,这里有一个类:

    package test;

class Anime{
    private String ID;
    private String name;
    private String altname;
    private String seasons;
    private String episodes;
    private String status;
    private String DS;
    private String have;
    private String left;
    private String plot;
    private String connect;
    private String image;

    public Anime(String ID, 
                 String name,
                 String altname,
                 String seasons,
                 String episodes,
                 String status,
                 String DS,
                 String have,
                 String left,
                 String plot,
                 String connect,
                 String image) {
        this.ID = ID;
        this.name = name;
        this.altname = altname;
        this.seasons = seasons;
        this.episodes = episodes;
        this.status = status;
        this.DS = DS;
        this.have = have;
        this.left = left;
        this.plot = plot;
        this.connect = connect;
        this.image = image;
    }

/*
 getters and setters here...
*/
    @Override
    public String toString() {
        return "Anime [ID=" + ID + 
               ", name=" + name + 
               ", altname=" + altname + 
               ", seasons=" + seasons + 
               ", episodes=" + episodes + 
               ", status=" + status + 
               ", DS=" + DS + 
               ", have=" + have + 
               ", left=" + left + 
               ", plot=" + plot + 
               ", connect=" + connect + 
               ", image=" + image + "]";
    }
}

最后,继承人xml:

<?xml version="1.0" encoding="UTF-8"?>
<Anime>
    <record ID="BL1">
        <name>Bleach</name>
        <altname>Burichi</altname>
        <seasons>16</seasons>
        <episodes>366</episodes>
        <status>Finished</status>
        <sound>Dubbed</sound>
        <have>All</have>
        <left>-/-</left>
        <plot>Ichigo gets grim reaper powers, fights reapers, hollows and everything in between</plot>
        <connect>Bleach movies</connect>
        <image>images/bleach.jpg</image>
    </record>
</Anime>

任何帮助将不胜感激,谢谢

2 个答案:

答案 0 :(得分:1)

嗨,基本上你对w3c dom xml元素的理解是错误的。 “name:,”altname“etc不是”Animie“元素的属性。那些是”记录“节点的”子节点“。所以首先你必须通过迭代”Animie“元素的子节点来获取”记录“节点。然后您可以遍历“record”元素的子节点,以便可以填充Anime对象。

这是你的“xmlmx类的一个简单实现。我必须使用一个地图,因为你已经省略了setter方法,只需要尝试修复脑中的xml概念就可以改进。

用这个替换你的课程。

package test;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import com.sun.org.apache.xerces.internal.dom.DeferredElementImpl;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;

public class xmlmx {

    public static void main(String[] args) {
        ArrayList<Anime> list = new ArrayList<Anime>();
        try {
            File inputFile = new File("test.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();
            System.out.println("Root element: " + doc.getDocumentElement().getNodeName());

            Node recordNode = null;
            NodeList childNodes = doc.getFirstChild().getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                if (childNodes.item(i).getNodeName().equals("record")) {
                    recordNode = childNodes.item(i);
                    break;
                }
            }
            System.out.println("----------------------------");


            Map<String, String> map = new HashMap<>();
            if (recordNode != null) {
                NodeList subNodes = recordNode.getChildNodes();
                for (int i = 0; i < subNodes.getLength(); i++) {
                    if (subNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
                        map.put(subNodes.item(i).getNodeName(), subNodes.item(i).getTextContent());
                    }
                }
            }

            String id = ((DeferredElementImpl) recordNode).getAttribute("ID");
            list.add(new Anime(id,
                    map.get("name"),
                    map.get("altname"),
                    map.get("seasons"),
                    map.get("episodes"),
                    map.get("status"),
                    map.get("DS"),
                    map.get("have"),
                    map.get("left"),
                    map.get("plot"),
                    map.get("connect"),
                    map.get("image")));

            System.out.println(list.get(0));


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

答案 1 :(得分:0)

使用ObjectMapper like Jackson FasterXML

new XmlMapper().readValue(yourDataAsInputStream, Anime.class);

或列表

new XmlMapper().readValue(yourDataAsInputStream, new TypeReference<List<Anime>>(){});

完整示例:

package stack47711679;

import java.util.List;
import org.junit.Test;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class HowToReadXmlToAPojoIn2017 {

    @Test
    public void readXmlToPojo() throws Exception {
        ObjectMapper mapper = new XmlMapper();
        Anime pojo = mapper.readValue(Thread.currentThread().getContextClassLoader().getResourceAsStream("47711679.xml"), Anime.class);
        System.out.println(pojo+"");
    }
    @Test
    public void readXmlToListOfPojo() throws Exception {
        ObjectMapper mapper = new XmlMapper();
        List<Anime> pojos = mapper.readValue(Thread.currentThread().getContextClassLoader().getResourceAsStream("47711679_v2.xml"), new TypeReference<List<Anime>>(){});
        System.out.println(pojos+"");
    }
}

您的POJO Anime.java

package stack47711679;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

public class Anime{
    @JacksonXmlProperty(isAttribute = true)
    public String  id;
    public String name;
    public String altname;
    public String seasons;
    public String episodes;
    public String status;
    public String DS;
    public String have;
    public String left;
    public String plot;
    public String connect;
    public String image;
    public String sound;
    public Anime(){
    }

    @Override
    public String toString() {
        return "Anime [ID=" + id + 
           ", name=" + name + 
           ", altname=" + altname + 
           ", seasons=" + seasons + 
           ", episodes=" + episodes + 
           ", status=" + status + 
           ", DS=" + DS + 
           ", have=" + have + 
           ", left=" + left + 
           ", plot=" + plot + 
           ", connect=" + connect + 
           ", sound=" + sound + 
           ", image=" + image + "]";
    }
}

使用Testdata:

47711679.xml

<?xml version="1.0" encoding="UTF-8"?>

<Anime id="1">
    <name>Bleach</name>
    <altname>Burichi</altname>
    <seasons>16</seasons>
    <episodes>366</episodes>
    <status>Finished</status>
    <sound>Dubbed</sound>
    <have>All</have>
    <left>-/-</left>
    <plot>Ichigo gets grim reaper powers, fights reapers, hollows and everything in between</plot>
    <connect>Bleach movies</connect>
    <image>images/bleach.jpg</image>
</Anime>

47711679_v2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Animes>
<Anime id="1">
    <name>Bleach</name>
    <altname>Burichi</altname>
    <seasons>16</seasons>
    <episodes>366</episodes>
    <status>Finished</status>
    <sound>Dubbed</sound>
    <have>All</have>
    <left>-/-</left>
    <plot>Ichigo gets grim reaper powers, fights reapers, hollows and everything in between</plot>
    <connect>Bleach movies</connect>
    <image>images/bleach.jpg</image>
</Anime>
<Anime id="2">
    <name>Something</name>
    <altname>else</altname>
    <seasons>21</seasons>
    <episodes>34</episodes>
    <status>to be continued</status>
    <sound>Dubbed</sound>
    <have>All</have>
    <left>-/-</left>
    <plot>Yes it has one</plot>
    <connect>Bleach movies</connect>
    <image>images/bleach.jpg</image>
</Anime>
</Animes>

打印: 对于47711679_v2.xml中的列表:

[Anime [ID=1, name=Bleach, altname=Burichi, seasons=16, episodes=366, status=Finished, DS=null, have=All, left=-/-, plot=Ichigo gets grim reaper powers, fights reapers, hollows and everything in between, connect=Bleach movies, sound=Dubbed, image=images/bleach.jpg], Anime [ID=2, name=Something, altname=else, seasons=21, episodes=34, status=to be continued, DS=null, have=All, left=-/-, plot=Yes it has one, connect=Bleach movies, sound=Dubbed, image=images/bleach.jpg]]

对于单个条目47711679.xml:

Anime [ID=1, name=Bleach, altname=Burichi, seasons=16, episodes=366, status=Finished, DS=null, have=All, left=-/-, plot=Ichigo gets grim reaper powers, fights reapers, hollows and everything in between, connect=Bleach movies, sound=Dubbed, image=images/bleach.jpg]

我使用了杰克逊2.8.6。

<dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.8.6</version>
    </dependency>