JAXB 中多次出现部分的空列表返回
Null List returning for Multiple Occurrence sections in JAXB
大家好,我是 JAXB 转换的新手。
我正在将 xml 解组为 java 个对象。对于单次出现的部分没有问题,但对于多次出现的部分则无法正确映射。每次我得到多次出现部分的空列表。
请给我建议任何有用的 url 或建议我需要进行的更改。
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;
}
}
Administartor.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 class。不用这个class
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);
}
}
请建议我解决这个问题
在你的classDesignTheory
定义
@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和下面的测试代码
验证了更正后的classes
@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
正确地具有包含 4 个元素的非空 List<DesignNotes>
。
大家好,我是 JAXB 转换的新手。
我正在将 xml 解组为 java 个对象。对于单次出现的部分没有问题,但对于多次出现的部分则无法正确映射。每次我得到多次出现部分的空列表。
请给我建议任何有用的 url 或建议我需要进行的更改。
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;
}
}
Administartor.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 class。不用这个class
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);
}
}
请建议我解决这个问题
在你的classDesignTheory
定义
@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和下面的测试代码
验证了更正后的classes@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
正确地具有包含 4 个元素的非空 List<DesignNotes>
。