首页 > 解决方案 > Java JAXB 从 XML 中解组 null 值

问题描述

尝试将 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>

我的 XML 文件的 Java 类:

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”匹配。但是,打印出来的值是 null 并且没有抛出错误消息。

有任何想法吗?谢谢!

标签: javajaxb

解决方案


为了让 JAXB 在那时解析到该类,XML<BlacklistCodeSet>必须是:

<BlacklistCodeSet>
    <blackListCode>D</blackListCode>
    <entityId>58241962</entityId>
</BlacklistCodeSet>

如果您创建一个实例BlackListCode并使用 JAXB 编组为 XML,您可以自己看到这一点。这是“调试”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 解组到对象中。


推荐阅读