java - JAXB 中多次出现部分返回空列表

标签 java java-8 jaxb

您好,我是 JAXB 转换新手。

我正在将 xml 解码为 java 对象。对于单次出现的部分没有问题,但对于多次出现的部分无法正确映射。每次我得到多次出现部分的空列表。

请向我建议任何有用的网址或建议我需要进行更改。

XML::

<?xml version="1.0" encoding="UTF-8"?>
<designTheory>
    <Administartor>
        <circuitId>67565675476</circuitId>
        <processId>567855</processId>
        <version>01</version>
        <circuitReferenceValue>ciruit-0001</circuitReferenceValue>
        <property>cal-circuit</property>
    </Administartor>
    <designSec>
        <priloc>priloc</priloc>
        <secloc>secloc</secloc>
        <remarks>remarks field</remarks>
    </designSec>
    <designNotes>
        <notesNumber>1</notesNumber>
        <notes>designNotes 1</notes>
    </designNotes>
    <designNotes>
        <notesNumber>2</notesNumber>
        <notes>designNotes 2</notes>
    </designNotes>
    <designNotes>
        <notesNumber>3</notesNumber>
        <notes>designNotes 3</notes>
    </designNotes>
    <designNotes>
        <notesNumber>4</notesNumber>
        <notes>designNotes 4</notes>
    </designNotes>
</designTheory>

代码片段如下:

DesignTheory.java

package org.manjunath.jaxbconversions.beans;

import java.util.List;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "designTheory")
public class DesignTheory {

    @XmlElement(name = "Administartor", required = true)
    private Administartor admin;

    @XmlElement(name = "designSec", required = true)
    private DesignSec designSec;

    @XmlElementWrapper
    @XmlElementRef(name = "designNotes")
    private List<JAXBElement<DesignNotes>> designNotesList;

    public void setAdministartor(Administartor admin){
        this.admin = admin;
    }

    public Administartor getAdministartor() {
        return admin;
    }

    public DesignSec getDesignSec() {
        return designSec;
    }

    public void setDesignSec(DesignSec designSec) {
        this.designSec = designSec;
    }


    public List<JAXBElement<DesignNotes>> getDlrnotes() {
        return designNotesList;
    }

    public void setDlrnotes(List<JAXBElement<DesignNotes>> designNotesList) {
        this.designNotesList = designNotesList;
    }
}

管理员.java

package org.manjunath.jaxbconversions.beans;

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

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Administartor")
public class Administartor {

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

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

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

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

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

    public String getcircuitId() {
        return circuitId;
    }

    public void setcircuitId(String circuitId) {
        this.circuitId = circuitId;
    }

    public String getprocessId() {
        return processId;
    }

    public void setprocessId(String processId) {
        this.processId = processId;
    }

    public String getVer() {
        return version;
    }

    public void setVer(String version) {
        this.version = version;
    }

    public String getcircuitReferenceValue() {
        return circuitReferenceValue;
    }

    public void setcircuitReferenceValue(String circuitReferenceValue) {
        this.circuitReferenceValue = circuitReferenceValue;
    }

    public String getproperty() {
        return property;
    }

    public void setproperty(String property) {
        this.property = property;
    }
}

DesignSec.java

package org.manjunath.jaxbconversions.beans;

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.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "designSec")
public class DesignSec {

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

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

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

    public String getpriloc() {
        return priloc;
    }

    public void setpriloc(String priloc) {
        this.priloc = priloc;
    }

    public String getSecloc() {
        return secloc;
    }

    public void setSecloc(String secloc) {
        this.secloc = secloc;
    }

    public String getremarks() {
        return remarks;
    }

    public void setEcspc(String remarks) {
        this.remarks = remarks;
    }
}

DesignNotes.java

package org.manjunath.jaxbconversions.beans;

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 = "designNotes")
@XmlAccessorType(XmlAccessType.FIELD)
public class DesignNotes {

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

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

    public String getnotesNumber() {
        return notesNumber;
    }

    public void setnotesNumber(String notesNumber) {
        this.notesNumber = notesNumber;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }
}

我发现 @XmlRegistry 和 @XmlElementDecl 可以解决我的问题。 但我不太擅长这些注释,但我尝试使用 ObjectFactory.java 类。没有使用这个类

ObjectFactory.java

package org.manjunath.jaxbconversions.factory;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;

import org.manjunath.jaxbconversions.beans.DesignNotes;

@XmlRegistry
public class ObjectFactory {

    private final static QName _DesignNotes_QNAME = new QName("designNotes");

    public ObjectFactory(){

    }

    @XmlElementDecl(name="designNotes")
    public JAXBElement<DesignNotes> createDesignNotes(DesignNotes value) {
        return new JAXBElement<DesignNotes>(_DesignNotes_QNAME, DesignNotes.class, value);
    }

}

请建议我解决这个问题

最佳答案

在你的类(class)DesignTheory定义

@XmlElementWrapper
@XmlElementRef(name = "designNotes")
private List<JAXBElement<DesignNotes>> designNotesList;

是错误的。 在您的 XML 中,您有

<designNotes>
  ...
</desinNotes>
<designNotes>
  ...
</designNotes>
...

但是您没有围绕这些 <designNotes> 提供额外的包装器像这样

<designNotesList>
  <designNotes>
    ...
  </desinNotes>
  <designNotes>
    ...
  </designNotes>
  ...
<designNotesList>

这就是为什么您需要删除 @XmlElementWrapper注释。

您应该将其类型从 List<JAXBElement<DesignNotes>> 更改为 至List<DesignNotes> 。所以你最终会得到

@XmlElementRef(name = "designNotes")
private List<DesignNotes> designNotesList;

同时将关联的 getter 和 setter 从 List<JAXBElement<DesignNotes>> 更改为 至List<DesignNotes> .

那么你就不需要 ObjectFactory不再存在并且可以将其完全删除。

我使用您的 XML 和以下测试代码验证了更正的类

@Test
public void testUnmarshall() throws Exception {
    JAXBContext context = JAXBContext.newInstance(DesignTheory.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    File file = new File("design-theory.xml");
    DesignTheory designTheory = (DesignTheory) unmarshaller.unmarshal(file);
    Assert.assertNotNull(designTheory.getDlrnotes());
    Assert.assertEquals(4, designTheory.getDlrnotes().size());
}

未编码的designTheory正确地有一个非空 List<DesignNotes>有 4 个元素。

关于java - JAXB 中多次出现部分返回空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51542316/

相关文章:

java - 使用流将多个 HashMap 的内容相加

jakarta.xml.bind.ContextFinder.handleClassCastException 处的 java.lang.NullPointerException

inheritance - JAXB 解码问题

java - 为什么这个在 Java 7 中编译而不在 Java 8 中编译?

java - ANTLR:词法分析器规则严格接受一个字母和多个字符的标记,而不是仅接受一个(Java)

java - 如何为 jni C++ 函数传递 ArrayList<Point>?

java - Spring应用启动报错: sources must not be empty

tomcat - 使用 couchbase 启动 spring boot 应用程序时出错 Error creating bean with name 'tomcatEmbeddedServletContainerFactory'

java - 获取 JAXBElement 列表,我想要预定义的 java 对象列表

java - Spring中的Json错误