Java - JAXB XML解组,包含可选字段

时间:2016-11-22 16:39:09

标签: java xml nullpointerexception jaxb

我在访问包含可选标记的解组XML文件字段时遇到问题。这是一个简单的例子,我为一个更复杂的案例做了补充:

<people>
    <persons>
        <person>
            <id>222</id>
            <pets>
                <pet>
                    <name age="2">Harry</name>
                </pet>
                <pet>
                    <name>Tiffany</name>
                </pet>
            </pets>
        </person>
        <person>
            <id>111</id>
            <pets>
                <pet value="1"></pet>
            </pets>
            <spouse>Frank</spouse>
        </person>
    </persons>
</people>

请注意,第二个人有配偶而第一个没有配偶。另外,第一个人的宠物有名字而第二个人的宠物没有。名叫哈利的宠物也有年龄属性。我想要展示的是,由于可选字段,我的XML文件可能包含不同的数据。

以下是我的JAXB模型类:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class People {

    @XmlElementWrapper
    @XmlElement(name="person")
    private List<Person> persons;

    public List<Person> getPersons() {
        return persons;
    }

    public void setPersons(List<Person> persons) {
        this.persons= persons;
    }

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlElement
    private int id;

    @XmlElementWrapper
    @XmlElement(name="pet")
    private List<Pet> pets;

    @XmlElement
    private String spouse;

    //getters and setters

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class pet {

    @XmlAttribute
    private int age;

    @XmlValue
    private String name;

    //getters and setters

}

现在,让我们说我只想打印所有宠物的名字。

for (Person person : people.getPersons()) {
    for (Pet pet : person.getPets()) {
        System.out.println("Pet name: " + pet.getName());
    }
}

如果缺少内部标记,我将获得NullPointerException。有趣的是,如果你只是在人员层中搜索一个字段,它就会跳过XML标记,好像它不存在一样,如:

for (Person person : people.getPersons()) {
    System.out.println("Spouse: " + person.getSpouse());
}

即使第一个人没有配偶,上述命令仍然有效。它只提供字符串“null”,这对我很有用。

我尝试过的解决方案 - 在iftry-catch语句中包装每个字段(我不喜欢这样做,因为有数百个XML标记)。如果您有任何建议,请告诉我。感谢。

1 个答案:

答案 0 :(得分:1)

您示例中的NullPointerException非常明显。

System.out.println("Pet name: " + people.getPerson().get(i).getPet().getName());

问题是,当你没有宠物时,getPet()会返回null。随后,您在getName()上致电null,因此您获得了例外。在第二个示例中,不会发生执行,因为getSpouse()会返回null,但System.out.println(...)会自动将其转换为字符串 null

即使看起来很乏味,但在遍历列表或字段时,您必须明确检查null的属性。 从不使用try-catch执行此操作!异常处理是一种繁重的机制,您绝不应该将此概念滥用于null检查。