使用STAX JAVA读取XML中元素的多个子元素

huangapple go评论43阅读模式
英文:

Read multiple child of Element in XML using STAX JAVA

问题

这是你想要的输出的方法:

public static void displayPeopleWithItems() {
    ArrayList<Person> people = personDAO.getPeople();
    if (people != null) {
        for (Person person : people) {
            System.out.println(person.getName());
            for (String item : person.getItems()) {
                System.out.println("    " + item);
            }
        }
    }
}

请确保 Person 类有一个名为 getItems() 的方法,以返回该人的所有项目作为字符串列表。

英文:

How do I read all childrem of Item element and store the in an object

This is my sample xml file

&lt;People&gt;
  &lt;Person&gt;
    &lt;Name&gt;Ben&lt;/Name&gt;
    &lt;Items&gt;
      &lt;Item&gt;Pen&lt;/Item&gt;
      &lt;Item&gt;Paper&lt;/Item&gt;
      &lt;Item&gt;Books&lt;/Item&gt;
    &lt;/Items&gt;
  &lt;/Person&gt;
  &lt;Person&gt;
    &lt;Name&gt;Alex&lt;/Name&gt;
    &lt;Items&gt;
      &lt;Item&gt;Pencil&lt;/Item&gt;
      &lt;Item&gt;Eraser&lt;/Item&gt;
    &lt;/Items&gt;
&lt;/People&gt;

I made a Person object with getters and setters

public class Person{ // SAMPLE OBJECT
    private String name; @getters and setters 
    private String item; @getters and setters
}

This is my method where it read

  public ArrayList&lt;Person&gt; getPeople(){

        people = new ArrayList&lt;&gt;();        
        Person a = null;        
        if (Files.exists(peoplePath))  // prevent the FileNotFoundException
        {
            // create the XMLInputFactory object
            XMLInputFactory inputFactory = XMLInputFactory.newFactory();
            try
            {
                // create a XMLStreamReader object
                FileReader fileReader =
                    new FileReader(peoplePath.toFile());
                XMLStreamReader reader =
                    inputFactory.createXMLStreamReader(fileReader);

                // read from the file
                while (reader.hasNext())
                {
                    int eventType = reader.getEventType();
                    switch (eventType)
                    {
                        case XMLStreamConstants.START_ELEMENT:
                            String elementName = reader.getLocalName();
                            if (elementName.equals(&quot;Person&quot;))
                            {
                                a = new Person();
                            }
                            if (elementName.equals(&quot;Name&quot;))
                            {
                                String name = reader.getElementText();
                                a.setName(name);                
                             }
                            
                            if (elementName.equals(&quot;Item&quot;))
                            {
                                String item= reader.getElementText();
                                a.setItem(item);
                            }
                            break;
                        case XMLStreamConstants.END_ELEMENT:
                            elementName = reader.getLocalName();
                            if (elementName.equals(&quot;Person&quot;))
                            {
                            	people.add(a);
                            }
                            break;
                        default:
                            break;
                    }
                    reader.next();
                }
            }
            catch (IOException | XMLStreamException e)
            {
                System.out.println(e);
                return null;
            }
        }
        return people;
    }


This method displays <br>
Ben<br>
Alex

but if I get the items it only using similar code, it displays <br>
Books<br>
Eraser

    public static void displayPeople(){
     
        ArrayList&lt;Person&gt; people = personDAO.getPeople();
        People p = null;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &lt; people.size(); i++)
        {
            a = people.get(i);
            sb.append(a.getName());          
            sb.append(&quot;\n&quot;);
        }
        System.out.println(sb.toString());
    }

I wanted to do this output

Ben
    Pen
    Paper
    Book
Alex
    Pencil 
    Eraser

答案1

得分: 0

首先,你的xml在结束之前缺少了Person元素的关闭标签。

</Person>

其次,你的Person类不太正确。Items应该是一个String列表,而不只是一个String。

public class Person {
    // 为简洁起见,私有关键字已被删除
    String name;
    List<String> items = new ArrayList<>();
}

第三,你的代码需要更新以使用项目列表,如下所示:

if (elementName.equals("Item")) {
    String item = reader.getElementText();
    a.getItems().add(item);
}

我其实在思考:
为什么你选择了Stax而不是JAXB?实际上,你的XML架构非常简单,可以使用JAXB处理。将XML转换为Java对象的代码几乎没有样板代码,这意味着使用JAXB,你的代码将更可读和易于维护。这只是我的个人观点。

英文:

First, your xml is missing the Person element closing just before the end.

&lt;/Person&gt;

Second, your Person class is not really correct. Items should be a list of String instead of just a String.

public class Person {
// private keyword is removed for brevity
    String name; 
    List&lt;String&gt; items = new ArrayList&lt;&gt;(); 
}

Third, your code needs to be updated to use the list of items as follows:

if (elementName.equals(&quot;Item&quot;))
{
	String item= reader.getElementText();
	a.getItems().add(item);
}

I'm actually wondering:
Why do you choose Stax instead of JAXB? Your XML schema is actually quite straight-forward to be handled with JAXB. And there will be very little boilerplate code for the conversion of XML to Java object, which means your code will be more readable and maintainable with JAXB. Just my 2 cents.

huangapple
  • 本文由 发表于 2020年8月2日 07:54:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63211111.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定