2016-11-22 52 views
0

我在访问包含可选标记的解组XML文件的字段方面存在问题。下面是一个简单的例子,我做了一个更复杂的情况:Java - 使用可选字段解组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标签)。如果您有任何建议,请告诉我。谢谢。

+0

缺少很多XML注释。此外,前两个例子是相同的。另外,'people.getPerson()。get(i).getPet.getName'没有意义,因为'getPet'是一个方法并返回一个列表? – thatguy

+0

您的XML示例也可能是错误的,因为''不包含'',但是'Dog'和'Cat'。 – thatguy

+0

你是对的,我很抱歉,如果这是一个不好的例子,但我只是为了说明一个简单的例子。这些字段可以替换为任何内容。至于.get(i),我会更新我的帖子以包含for循环。谢谢。 – rj2700

回答

1

你的例子中的NullPointerException很明显。

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

的问题是,当你没有宠物,getPet()回报null。随后,您致电getName()null,因此你会得到例外。在第二个例子中,不发生execption,因为getSpouse()回报null,但System.out.println(...)它转换成字符串自动。

尽管它看起来很乏味,但在遍历列表或字段时,您必须明确检查null的属性。 从来没有这样做与try-catch!异常处理是一个沉重的机制,你不应该滥用这个概念来检查null

+0

感谢您的回复!我想 - 我最担心的是 - 检查所有字段,看看它们是否为空。但是,为每个领域创建一堆if语句不是不好的做法吗?任何可能的方式来创建一个单独的方法来检查这个? – rj2700

+0

问题是,您的字段是可选的。如果字段为_required_,则可以对它们进行注释,以便JAXB检查字段并在'null'上引发错误。但是,如果这些字段是可选的,你基本上会说:我期望一个具体的值(一个'object!= null')或'null',两者都是** valid **输入。与其他应用程序一样,您可以在程序逻辑中处理这些数据,其中包括检查“null”。 “为每个领域创建一堆if语句”意味着什么?你究竟想通过这个实现什么? – thatguy

+0

我的意思是“创建一堆if语句”,正在包装if语句以查看“person”下的XML标记是否为null。所以如果它是空的,那么它可以被跳过。这是为了实现捕获XML中的所有数据字段。通过“显式检查[全部]属性为null”,你意味着什么? – rj2700