简体   繁体   中英

Unmarshalling xml with jaxb if the elements are the same, but different element values

Hello help please have the xml file in it some of the same elements, the elements differ in the content of the "name" attribute. These elements have different sets of items, how to perform unmarshal? Xml:

        <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>
        <service-broker>
            <adapters>
                <adapter name=\"cdb\">
                        <protocol>JDBC</protocol>
                        <datasource>CdbAdapterDS</datasource>
                </adapter>

                <adapter name=\"fmss-sc\">
                    <protocol>BBBC</protocol>
                    <fleet-uc18-reason-codes>
                            <code>2</code>
                            <code>3</code>
                    </fleet-uc18-reason-codes>
                </adapter>
            </adapters>  
        </service-broker>

I Need to perform the unmarshalling of the object 2 in the Cdb and FmssSc My attempts: General element - ServiceBroker.class

package jax;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "service-broker")
@XmlAccessorType(XmlAccessType.FIELD)
public class ServiceBroker {

    @XmlElement(name = "adapters")
    private Adapters adapters;

    public Adapters getAdapters() {
        return adapters;
    }

    public void setAdapters(Adapters adapters) {
        this.adapters = adapters;
    }
}

Adapters.class

package jax;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

@XmlAccessorType(XmlAccessType.FIELD)
class Adapters {

    @XmlElement
    private Cdb cdb;

    @XmlElement
    private FmssSc fmssSc;

    public Cdb getCdb() {
        return cdb;
    }

    public void setCdb(Cdb cdb) {
        this.cdb = cdb;
    }

    public FmssSc getFmssSc() {
        return fmssSc;
    }

    public void setFmssSc(FmssSc fmssSc) {
        this.fmssSc = fmssSc;
    }
}

Cdb.class

package jax;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
class Cdb {

    @XmlElement(name = "protocol")
    private String protocol;

    @XmlElement(name = "datasource")
    private String datasource;

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getDatasource() {
        return datasource;
    }

    public void setDatasource(String datasource) {
        this.datasource = datasource;
    }
}

FmssSc.class

package jax;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

@XmlAccessorType(XmlAccessType.FIELD)
class FmssSc {

    @XmlElement(name = "protocol")
    private String protocol;

    @XmlElementWrapper(name = "fleet-uc18-reason-codes")
    @XmlElement(name = "code")
    private List<String> code = new ArrayList<>();

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public List<String> getCode() {
        return code;
    }

    public void setCode(List<String> code) {
        this.code = code;
    }
}

Demo:

package jax;

import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class Jax {

    public static final String adapter =
            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
            "<service-broker>" + 
                "<adapters>" +
                    "<adapter name=\"cdb\">" +
                            "<protocol>JDBC</protocol>" +
                            "<datasource>CdbAdapterDS</datasource>" +
                    "</adapter>" +

                    "<adapter name=\"fmss-sc\">" +
                        "<protocol>BBBC</protocol>" +
                        "<fleet-uc18-reason-codes>" +
                                "<code>2</code>" +
                                "<code>3</code>" +
                        "</fleet-uc18-reason-codes>" +
                    "</adapter>" +
                "</adapters>"  +
            "</service-broker>";

    public static void main(String[] args) throws JAXBException {
        Jax jax = new Jax();
        jax.shouldUnmarshallAdapter();
    }

    public void shouldUnmarshallAdapter() throws JAXBException {
        StringReader reader = new StringReader(adapter);
        JAXBContext context = JAXBContext.newInstance(ServiceBroker.class);
        Unmarshaller u = context.createUnmarshaller();
        ServiceBroker sb = (ServiceBroker) u.unmarshal(reader);
        System.out.println(sb.getAdapters().getCdb().getProtocol());
    }
}

Error:

Exception in thread "main" java.lang.NullPointerException
    at jax.Jax.shouldUnmarshallAdapter(Jax.java:39)
    at jax.Jax.main(Jax.java:31)

The tagname "adapter" in the XML has no equivalent in your Java classes, ie there is no member of the class "Adapters" with that name, so in fact all XML with that tag will be ignored, hence the variable cdb in the Adapters instance is null, therefore .. NPE. And: The attribute "name" in your XML will by no way be used by Jaxb to map all sub-tags either to the cdb or fmssSc member. Your Java code would map to an XML of that structure:

<service-Broker>
   <adapters>
      <cdb>
        <protocol>
        <datasource>
      <fmssSc>
        <protocol>
        ....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM