【问题标题】:add same name xml node to a arrayList将同名 xml 节点添加到 arrayList
【发布时间】:2018-11-13 06:43:09
【问题描述】:

我在将 xml 文件节点添加到对象时遇到问题

xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Users>
    <User firstName="john">
        <lastName>fall</lastName>
        <score>12</score>
        <score>11</score>
        <score>9</score>
    </User>
    <User firstName="alen">
        <lastName>spring</lastName>
        <score>17</score>
        <score>15</score>
    </User>
</Users>

xml 文件具有相同的score 节点但值不同

用户类有 3 个字段 fNamelNameList&lt;Integer&gt; scores 和分数文件用于在 xml 文件中添加分数节点。

用户类别:

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

public class User {

    private String fName;
    private String lName;
    private List<Integer> scores;

    public User() {
        this("firstName", "lastName", new ArrayList<>());

    }

    public User(String fName, String lName, List<Integer> scores) {

        setfName(fName);
        setlName(lName);
        setScores(scores);

    }

    public String getfName() {
        return fName;
    }

    public void setfName(String fName) {
        this.fName = fName;
    }

    public String getlName() {
        return lName;
    }

    public void setlName(String lName) {
        this.lName = lName;
    }

    public List<Integer> getScores() {
        return scores;
    }

    public void setScores(List<Integer> scores) {
        this.scores = scores;
    }

    public String toString() {

        StringBuilder sb = new StringBuilder();

        getScores().forEach(val -> sb.append(String.format("%12d\n%18s", val, "")));

        return String.format("%-12s%s%s\n\n", getfName(), getlName(), sb.toString());

    }

}

现在我尝试读取 xml 文件节点并添加到用户对象列表:

readXml 方法:

public static void readXml(String xmlFile) {

    Document doc = null;

    NodeList nList = null;
    NodeList nScoreList = null;
    Element el = null;

    String fName = null;
    String lName = null;
    List<Integer> scores;

    try {

        doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);
        doc.normalizeDocument();

        nList = doc.getElementsByTagName("User");

        scores = new ArrayList<>();

        for (int i = 0; i < nList.getLength(); i++) {

            el = (Element) nList.item(i);
            fName = el.getAttribute("firstName");
            lName = el.getElementsByTagName("lastName").item(0).getTextContent();

            nScoreList = el.getElementsByTagName("score");

            for (int j = 0; j < nScoreList.getLength(); j++)
                scores.add(Integer.valueOf(nScoreList.item(j).getTextContent()));

            System.out.println(new User(fName, lName, scores));

        }

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

}

输出是:

john         fall           12
                            11
                             9



alen        spring          12
                            11
                             9
                            17
                            15

但我需要这个输出:

john         fall           12
                            11
                             9


alen        spring          17
                            15

现在我该怎么解决这个问题?

【问题讨论】:

标签: java xml object dom arraylist


【解决方案1】:

您正在重用 xml 中所有元素的分数列表,因此每个新元素都将继承前一个元素的所有分数。为 xml 中的每个元素创建一个新列表,如下所示:

try {

    doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);
    doc.normalizeDocument();

    nList = doc.getElementsByTagName("User");

    // By placing the list here, all the scores get appended
    // throughout all the elements in the xml
    // scores = new ArrayList<>();

    for (int i = 0; i < nList.getLength(); i++) {

        el = (Element) nList.item(i);
        fName = el.getAttribute("firstName");
        lName = el.getElementsByTagName("lastName").item(0).getTextContent();

        nScoreList = el.getElementsByTagName("score");

        // Now scores is a fresh list every time you get a new element
        scores = new ArrayList<>();
        for (int j = 0; j < nScoreList.getLength(); j++)
            scores.add(Integer.valueOf(nScoreList.item(j).getTextContent()));

        System.out.println(new User(fName, lName, scores));

    }

}

【讨论】:

    【解决方案2】:

    不要做所有这些工作。只需使用 XML 序列化程序进行序列化。 SimpleXml 可以做到:

    public class Users {
        @XmlName("User")
        public List<User> users;
    }
    public class User {
        @XmlAttribute
        @XmlName("firstName")
        private String fName;
        @XmlName("lastName")
        private String lName;
        @XmlName("score")
        private List<Integer> scores;
    }
    
    final String data = ...
    final SimpleXml simple = new SimpleXml();
    final Users users = simple.fromXml(data, Users.class);
    for (final User u : users.users) {
        System.out.println(u.fName + " " + u.lName + ": " + u.scores.toString());
    }
    

    将输出:

    john fall: [12, 11, 9]
    alen spring: [17, 15]
    

    来自 Maven 中心:

    <dependency>
        <groupId>com.github.codemonstur</groupId>
        <artifactId>simplexml</artifactId>
        <version>1.4.0</version>
    </dependency>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多