Java JAXB 从 XML 解组空值
Java JAXB unmarshaling null value from XML
我在尝试将值从 XML 提取到 Java 时遇到了一些问题。我的 XML 文件示例输入:
<?xml version="1.0" encoding="UTF-8" ?>
<TRB_TRX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEADER ReqNotf="N" TransactionCode="L9_BLACKLIST_SET" PublisherApplID="CL" PublisherApplThreadID="1" EntityId="58241962" RoutingId="2626289" EntityType="ACCOUNT" IssueDate="2019-06-18T23:59:59" EffectiveDate="2019-06-18T23:59:59"/>
<DATA>
<BlacklistCodeSet>
<TransactionHeaderInfoExt>
<ApplicationId>CL</ApplicationId>
<RequestDate>2019-06-18T23:59:59</RequestDate>
</TransactionHeaderInfoExt>
<ClEntityIdInfoExt>
<EntityId>58241962</EntityId>
<EntityType>ACCOUNT</EntityType>
</ClEntityIdInfoExt>
<GeneralCollectionEntityInfoExt>
<BlacklistCode>D</BlacklistCode>
</GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>
</DATA>
</TRB_TRX>
我的 Java class XML 文件:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="BlacklistCodeSet")
public class BlackListCode {
String entityId;
String blackListCode;
public String getEntityId() {
return entityId;
}
public void setEntityId(String entityId) {
this.entityId = entityId;
}
public String getBlackListCode() {
return blackListCode;
}
public void setBlackListCode(String blackListCode) {
this.blackListCode = blackListCode;
}
@Override
public String toString() {
return "BlackListCode{" +
"entityId='" + entityId + '\'' +
", blackListCode='" + blackListCode + '\'' +
'}';
}
}
我提取值的代码:
XMLInputFactory xif = XMLInputFactory.newFactory();
FileReader reader = new FileReader("src/main/resources/xml/blacklistcode.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(reader);
try {
JAXBContext jc = JAXBContext.newInstance(BlackListCode.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
while (xsr.hasNext()) {
while (xsr.hasNext() && (!xsr.isStartElement() || !xsr.getLocalName().equals("BlacklistCodeSet"))) {
xsr.next();
}
if (xsr.hasNext()) {
BlackListCode blacklistcode = (BlackListCode) unmarshaller.unmarshal(xsr);
log.debug("BLACKLIST CODE IS " + blacklistcode);
log.debug("ACCOUNT NO IS " + blacklistcode.getEntityId());
}
}
}catch (Exception e){
e.printStackTrace();
}
在提取值之前,我确实尝试循环节点直到它匹配 "BlacklistCodeSet"。但是,打印出的值是空的,并且没有抛出任何错误消息。
有什么想法吗?谢谢!
为了让 JAXB 在那个时候解析成 class,<BlacklistCodeSet>
的 XML 必须是:
<BlacklistCodeSet>
<blackListCode>D</blackListCode>
<entityId>58241962</entityId>
</BlacklistCodeSet>
如果您创建 BlackListCode
的实例并使用 JAXB 编组到 XML,您可以自己看到这一点。这是 "debug" JAXB 的最佳方式。
BlackListCode blackListCode = new BlackListCode();
blackListCode.setEntityId("58241962");
blackListCode.setBlackListCode("D");
JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);
如您所见,JAXB 所需的 XML 与您实际提供给 JAXB 的 XML 有很大不同。这些元素甚至没有正确命名,以小写字母开头,因此您需要指定 @XmlElement
注释才能正确命名它们,并且您需要额外的对象才能获得更复杂的 XML。
@XmlRootElement(name = "BlacklistCodeSet")
class BlackListCode {
private ClEntityIdInfoExt clEntityIdInfoExt;
private GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt;
@XmlElement(name = "ClEntityIdInfoExt")
public ClEntityIdInfoExt getClEntityIdInfoExt() {
return this.clEntityIdInfoExt;
}
public void setClEntityIdInfoExt(ClEntityIdInfoExt clEntityIdInfoExt) {
this.clEntityIdInfoExt = clEntityIdInfoExt;
}
@XmlElement(name = "GeneralCollectionEntityInfoExt")
public GeneralCollectionEntityInfoExt getGeneralCollectionEntityInfoExt() {
return this.generalCollectionEntityInfoExt;
}
public void setGeneralCollectionEntityInfoExt(GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt) {
this.generalCollectionEntityInfoExt = generalCollectionEntityInfoExt;
}
@Override
public String toString() {
return "BlackListCode{entityId='" + this.clEntityIdInfoExt.getEntityId() + '\'' +
", BlacklistCode='" + this.generalCollectionEntityInfoExt.getBlacklistCode() + '\'' + '}';
}
}
class ClEntityIdInfoExt {
private String entityId;
public ClEntityIdInfoExt() {
}
public ClEntityIdInfoExt(String entityId) {
this.entityId = entityId;
}
@XmlElement(name = "EntityId")
public String getEntityId() {
return this.entityId;
}
public void setEntityId(String entityId) {
this.entityId = entityId;
}
}
class GeneralCollectionEntityInfoExt {
private String BlacklistCode;
public GeneralCollectionEntityInfoExt() {
}
public GeneralCollectionEntityInfoExt(String blacklistCode) {
this.BlacklistCode = blacklistCode;
}
@XmlElement(name = "BlacklistCode")
public String getBlacklistCode() {
return this.BlacklistCode;
}
public void setBlacklistCode(String blacklistCode) {
this.BlacklistCode = blacklistCode;
}
}
测试
BlackListCode blackListCode = new BlackListCode();
blackListCode.setClEntityIdInfoExt(new ClEntityIdInfoExt("58241962"));
blackListCode.setGeneralCollectionEntityInfoExt(new GeneralCollectionEntityInfoExt("D"));
JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BlacklistCodeSet>
<ClEntityIdInfoExt>
<EntityId>58241962</EntityId>
</ClEntityIdInfoExt>
<GeneralCollectionEntityInfoExt>
<BlacklistCode>D</BlacklistCode>
</GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>
现在生成的 XML 与预期的 XML 匹配,JAXB 可以正确地将 XML 解组到对象中。
我在尝试将值从 XML 提取到 Java 时遇到了一些问题。我的 XML 文件示例输入:
<?xml version="1.0" encoding="UTF-8" ?>
<TRB_TRX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEADER ReqNotf="N" TransactionCode="L9_BLACKLIST_SET" PublisherApplID="CL" PublisherApplThreadID="1" EntityId="58241962" RoutingId="2626289" EntityType="ACCOUNT" IssueDate="2019-06-18T23:59:59" EffectiveDate="2019-06-18T23:59:59"/>
<DATA>
<BlacklistCodeSet>
<TransactionHeaderInfoExt>
<ApplicationId>CL</ApplicationId>
<RequestDate>2019-06-18T23:59:59</RequestDate>
</TransactionHeaderInfoExt>
<ClEntityIdInfoExt>
<EntityId>58241962</EntityId>
<EntityType>ACCOUNT</EntityType>
</ClEntityIdInfoExt>
<GeneralCollectionEntityInfoExt>
<BlacklistCode>D</BlacklistCode>
</GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>
</DATA>
</TRB_TRX>
我的 Java class XML 文件:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="BlacklistCodeSet")
public class BlackListCode {
String entityId;
String blackListCode;
public String getEntityId() {
return entityId;
}
public void setEntityId(String entityId) {
this.entityId = entityId;
}
public String getBlackListCode() {
return blackListCode;
}
public void setBlackListCode(String blackListCode) {
this.blackListCode = blackListCode;
}
@Override
public String toString() {
return "BlackListCode{" +
"entityId='" + entityId + '\'' +
", blackListCode='" + blackListCode + '\'' +
'}';
}
}
我提取值的代码:
XMLInputFactory xif = XMLInputFactory.newFactory();
FileReader reader = new FileReader("src/main/resources/xml/blacklistcode.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(reader);
try {
JAXBContext jc = JAXBContext.newInstance(BlackListCode.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
while (xsr.hasNext()) {
while (xsr.hasNext() && (!xsr.isStartElement() || !xsr.getLocalName().equals("BlacklistCodeSet"))) {
xsr.next();
}
if (xsr.hasNext()) {
BlackListCode blacklistcode = (BlackListCode) unmarshaller.unmarshal(xsr);
log.debug("BLACKLIST CODE IS " + blacklistcode);
log.debug("ACCOUNT NO IS " + blacklistcode.getEntityId());
}
}
}catch (Exception e){
e.printStackTrace();
}
在提取值之前,我确实尝试循环节点直到它匹配 "BlacklistCodeSet"。但是,打印出的值是空的,并且没有抛出任何错误消息。
有什么想法吗?谢谢!
为了让 JAXB 在那个时候解析成 class,<BlacklistCodeSet>
的 XML 必须是:
<BlacklistCodeSet>
<blackListCode>D</blackListCode>
<entityId>58241962</entityId>
</BlacklistCodeSet>
如果您创建 BlackListCode
的实例并使用 JAXB 编组到 XML,您可以自己看到这一点。这是 "debug" JAXB 的最佳方式。
BlackListCode blackListCode = new BlackListCode();
blackListCode.setEntityId("58241962");
blackListCode.setBlackListCode("D");
JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);
如您所见,JAXB 所需的 XML 与您实际提供给 JAXB 的 XML 有很大不同。这些元素甚至没有正确命名,以小写字母开头,因此您需要指定 @XmlElement
注释才能正确命名它们,并且您需要额外的对象才能获得更复杂的 XML。
@XmlRootElement(name = "BlacklistCodeSet")
class BlackListCode {
private ClEntityIdInfoExt clEntityIdInfoExt;
private GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt;
@XmlElement(name = "ClEntityIdInfoExt")
public ClEntityIdInfoExt getClEntityIdInfoExt() {
return this.clEntityIdInfoExt;
}
public void setClEntityIdInfoExt(ClEntityIdInfoExt clEntityIdInfoExt) {
this.clEntityIdInfoExt = clEntityIdInfoExt;
}
@XmlElement(name = "GeneralCollectionEntityInfoExt")
public GeneralCollectionEntityInfoExt getGeneralCollectionEntityInfoExt() {
return this.generalCollectionEntityInfoExt;
}
public void setGeneralCollectionEntityInfoExt(GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt) {
this.generalCollectionEntityInfoExt = generalCollectionEntityInfoExt;
}
@Override
public String toString() {
return "BlackListCode{entityId='" + this.clEntityIdInfoExt.getEntityId() + '\'' +
", BlacklistCode='" + this.generalCollectionEntityInfoExt.getBlacklistCode() + '\'' + '}';
}
}
class ClEntityIdInfoExt {
private String entityId;
public ClEntityIdInfoExt() {
}
public ClEntityIdInfoExt(String entityId) {
this.entityId = entityId;
}
@XmlElement(name = "EntityId")
public String getEntityId() {
return this.entityId;
}
public void setEntityId(String entityId) {
this.entityId = entityId;
}
}
class GeneralCollectionEntityInfoExt {
private String BlacklistCode;
public GeneralCollectionEntityInfoExt() {
}
public GeneralCollectionEntityInfoExt(String blacklistCode) {
this.BlacklistCode = blacklistCode;
}
@XmlElement(name = "BlacklistCode")
public String getBlacklistCode() {
return this.BlacklistCode;
}
public void setBlacklistCode(String blacklistCode) {
this.BlacklistCode = blacklistCode;
}
}
测试
BlackListCode blackListCode = new BlackListCode();
blackListCode.setClEntityIdInfoExt(new ClEntityIdInfoExt("58241962"));
blackListCode.setGeneralCollectionEntityInfoExt(new GeneralCollectionEntityInfoExt("D"));
JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BlacklistCodeSet>
<ClEntityIdInfoExt>
<EntityId>58241962</EntityId>
</ClEntityIdInfoExt>
<GeneralCollectionEntityInfoExt>
<BlacklistCode>D</BlacklistCode>
</GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>
现在生成的 XML 与预期的 XML 匹配,JAXB 可以正确地将 XML 解组到对象中。