如果元素相同但元素值不同,则使用jaxb解组xml

时间:2016-06-02 15:07:56

标签: java xml jaxb unmarshalling

您好帮助请在其中包含xml文件中的一些相同元素,这些元素在" name"的内容上有所不同。属性。这些元素有不同的项目集,如何执行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>

我需要在Cdb和FmssSc中执行对象2的解组 我的尝试: 常规元素 - 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;
    }
}

演示:

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());
    }
}

错误:

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

1 个答案:

答案 0 :(得分:0)

标记名&#34;适配器&#34;在XML中没有相应的Java类,即没有类的成员&#34; Adapters&#34;使用该名称,实际上所有带有该标记的XML都将被忽略,因此Adapters实例中的变量cdb为null,因此为.. NPE。 并且:属性&#34; name&#34;在您的XML中,Jaxb绝不会将所有子标记映射到cdb或fmssSc成员。您的Java代码将映射到该结构的XML:

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