带有可选字段的Java-JAXBXML解组
我在访问未经授权的XML文件的字段时遇到问题,这些文件包含可选标记。下面是我为一个更复杂的案例编写的一个简单示例:带有可选字段的Java-JAXBXML解组,java,xml,nullpointerexception,jaxb,Java,Xml,Nullpointerexception,Jaxb,我在访问未经授权的XML文件的字段时遇到问题,这些文件包含可选标记。下面是我为一个更复杂的案例编写的一个简单示例: <people> <persons> <person> <id>222</id> <pets> <pet> <name age="2">Harr
<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>
如果缺少一个内部标记,我将得到一个NullPointerException
。不过,有趣的是,如果您只是在人员层中搜索一个字段,它将跳过XML标记,就像它不存在一样,如:
for (Person person : people.getPersons()) {
System.out.println("Spouse: " + person.getSpouse());
}
即使第一个人没有配偶,上述命令仍然有效。它只提供字符串“null”,这对我来说很好
我尝试过的解决方案-将每个字段包装在
if
或try-catch
语句中(我不喜欢这样做,因为有数百个XML标记)。如果你有任何建议,请告诉我。谢谢。您的示例中的NullPointerException
非常明显
System.out.println("Pet name: " + people.getPerson().get(i).getPet().getName());
问题是,当您没有宠物时,getPet()
返回null
。随后,在null
上调用getName()
,因此得到异常。在第二个示例中,执行选项没有出现,因为getparty()
返回null
,但System.out.println(…)
会自动将其转换为字符串null
尽管这看起来很乏味,但在遍历列表或字段时,您必须显式地检查属性的
null
千万不要用试试catch
!异常处理是一种繁重的机制,您不应该将此概念用于null
检查。缺少很多XML注释。此外,前两个示例是相同的。另外,people.getPerson().get(i).getPet.getName
没有意义,因为getPet
是一个方法并返回一个列表?您的XML示例也可能是错误的,因为
不包括
,而是狗和猫。您是对的,如果这是一个不好的例子,我很抱歉,但我只是在飞行中做这个来说明一个简单的例子。这些字段可以替换为任何内容。至于.get(i),我将更新我的帖子以包含for循环。谢谢。谢谢你的回复!我想,我最担心的事情发生了——检查所有字段是否为空。但是为每个字段创建一组if语句不是很糟糕吗?有没有可能创建一个单独的方法来检查这个问题?问题是,您的字段是可选的。如果需要一个字段,可以对其进行注释,因此JAXB会检查字段并在null
上引发错误。但是,如果字段是可选的,您基本上会说:我期望一个具体的值(一个对象!=null
)或null
,两者都是有效的输入。与其他应用程序一样,您可以在程序逻辑中处理这些数据,包括检查null
。“为每个字段创建一组if语句”是什么意思?实际上,您希望通过此实现什么?我所说的“创建一组if语句”是指包装if语句,以查看“person”下的XML标记是否为null。因此,如果它为null,则可以跳过它。这是为了实现捕获XML中的所有数据字段。“显式检查[all]属性是否为null”是什么意思?显式检查null
我的意思是if(instance!=null){…}
。在这种情况下,必须检查null
,因此不能避免if语句。但是,如果您有一个列表persons
,并选中if(persons!=null){…}
,则您有一个if语句。然后您可以使用for(person-personInList:persons){…}
。在循环体中,所有personInList!=空
。如果您不想遍历列表,但检查是否有人,只需使用If(persons!=null&&persons.size()>0)
。这样,它就不像你想象的那样冗长了。这对你有帮助吗?嘿@thatguy,我知道这个线程有点旧了,但是另一个替代方案可以使用可选类(在Java8中引入)吗?我找到了这个链接,它似乎与这个问题相一致()。但是,我不太确定是否需要封装JAXB中所有子级的每个成员属性?
for (Person person : people.getPersons()) {
System.out.println("Spouse: " + person.getSpouse());
}
System.out.println("Pet name: " + people.getPerson().get(i).getPet().getName());