【问题标题】:Unmarshalling xml with jaxb if the elements are the same, but different element values如果元素相同但元素值不同,则使用 jaxb 解组 xml
【发布时间】:2016-06-02 15:07:55
【问题描述】:

您好,请帮助,请在xml文件中包含一些相同的元素,这些元素在“name”属性的内容上有所不同。这些元素有不同的集合项,如何进行解组? 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)

【问题讨论】:

标签: java xml jaxb unmarshalling


【解决方案1】:

XML 中的标记名“适配器”在您的 Java 类中没有等效项,即“适配器”类中没有具有该名称的成员,因此实际上所有具有该标记的 XML 都将被忽略,因此变量 cdb在 Adapters 实例中为空,因此 .. NPE。 并且:Jaxb 绝不会使用 XML 中的属性“名称”将所有子标签映射到 cdb 或 fmssSc 成员。您的 Java 代码将映射到该结构的 XML:

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

【讨论】:

  • 感谢您的评论,但如何解组此 xml?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
相关资源
最近更新 更多