[英]jaxb binding returning null value for nested map xml implementation
[英]JAXB returning null for a nested xml containing collections
我想將以下xml解組為另一個父對象,如下所述。 但它總是返回NULL。
傳入XML:
<contentFiles>
<contentFile>
<contentFileName>cwb_reg_content_IB20C0F504A9A11E281E4C8BF76F4977C.pdf</contentFileName>
<title><![CDATA[SEC No-Action Guidance Expanding the Definition of “Ready Market” for Certain Foreign Equity Securities]]></title>
<sourcePublicationDate>20121219</sourcePublicationDate>
<alternateDocNumbers>
<alternateDocNumber>12345-b</alternateDocNumber>
</alternateDocNumbers>
<citesAffected>
<cite>SEA Rule 15c3-1</cite>
</citesAffected>
</contentFile>
</contentFiles>
與<contentFiles>
對應的父類
@XmlRootElement(name = "contentFiles")
public class RtSuperQuickMetadata
{
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
public RtSuperQuickMetadata()
{
rtSuperQuickMetadataItems = new ArrayList<RtSuperQuickMetadataItem>();
}
public List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems()
{
return rtSuperQuickMetadataItems;
}
public void setRtSuperQuickMetadataItems(
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems)
{
this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems;
}
}
與<contentFile>
對應的父類
@XmlRootElement(name = "contentFile")
public class RtSuperQuickMetadataItem
{
private String contentFileName;
private String title;
private String sourcePublicationDate;
private List<AlternateDocNumber> alternateDocNumbers;
private List<Cite> citesAffected;
public RtSuperQuickMetadataItem()
{
alternateDocNumbers = new ArrayList<AlternateDocNumber>();
citesAffected = new ArrayList<Cite>();
}
public List<AlternateDocNumber> getAlternateDocNumbers()
{
return alternateDocNumbers;
}
public List<Cite> getCitesAffected()
{
return citesAffected;
}
public String getContentFileName()
{
return contentFileName;
}
public String getSourcePublicationDate()
{
return sourcePublicationDate;
}
public String getTitle()
{
return title;
}
public void setAlternateDocNumbers(List<AlternateDocNumber> alternateDocNumbers)
{
this.alternateDocNumbers = alternateDocNumbers;
}
public void setCitesAffected(List<Cite> citesAffected)
{
this.citesAffected = citesAffected;
}
public void setContentFileName(String contentFileName)
{
this.contentFileName = contentFileName;
}
public void setSourcePublicationDate(String sourcePublicationDate)
{
this.sourcePublicationDate = sourcePublicationDate;
}
public void setTitle(String title)
{
this.title = title;
}
}
@XmlRootElement(name = "alternateDocNumber")
class AlternateDocNumber
{
private String alternateDocNumber;
public String getAlternateDocNumber()
{
return alternateDocNumber;
}
public void setAlternateDocNumber(String alternateDocNumber)
{
this.alternateDocNumber = alternateDocNumber;
}
@Override
public String toString()
{
return "AlternateDocNumber [alternateDocNumber=" + alternateDocNumber + "]";
}
}
@XmlRootElement(name = "cite")
class Cite
{
private String cite;
public String getCite()
{
return cite;
}
public void setCite(String cite)
{
this.cite = cite;
}
@Override
public String toString()
{
return "Cite [cite=" + cite + "]";
}
}
使用JAXB的Unmarshaller代碼:
public RtSuperQuickMetadata unmarshallXml(final File metadataFile)
throws JAXBException, FileNotFoundException
{
RtSuperQuickMetadata rtSuperQuickMetadata = null;
try
{
JAXBContext jc = JAXBContext.newInstance(RtSuperQuickMetadata.class);
Unmarshaller um = jc.createUnmarshaller();
rtSuperQuickMetadata =
(RtSuperQuickMetadata) um.unmarshal(metadataFile);
}
catch (JAXBException e)
{
String msg = "Malformed XML supplied as Metadata" + " Msg " + e.getMessage();
LOG.error(msg, e);
throw new RuntimeException(msg, e);
}
return rtSuperQuickMetadata;
}
你有太多的XmlRootElements
,你通常只想使用top元素。 你想要做的是將孩子標記為XmlElement
。
從除你的根元素之外的所有元素(即RtSuperQuickMetadata
)中刪除XmlRootElement
注釋,並在它們將從中加載它們的類中用XmlElement
標記它們。
因此,作為示例,以下是RtSuperQuickMetadata
類的外觀:
@XmlRootElement(name = "contentFiles")
class RtSuperQuickMetadata
{
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
public RtSuperQuickMetadata()
{
rtSuperQuickMetadataItems = new ArrayList<RtSuperQuickMetadataItem>();
}
@XmlElement(name = "contentFile")
public List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems()
{
return rtSuperQuickMetadataItems;
}
public void setRtSuperQuickMetadataItems(
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems)
{
this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems;
}
}
將此原則轉移到alternateDocNumbers
並citesAffected
。
如果您想看一個Unmarshaller
如何根據您的注釋認為您的XML格式化的示例,您可以在代碼中創建您的結構並使用Marshaller
。 這是一個快速而丑陋的例子:
RtSuperQuickMetadata rtSuperQuickMetadata = new RtSuperQuickMetadata();
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems = new ArrayList<RtSuperQuickMetadataItem>();
rtSuperQuickMetadata.setRtSuperQuickMetadataItems(rtSuperQuickMetadataItems);
RtSuperQuickMetadataItem item = new RtSuperQuickMetadataItem();
rtSuperQuickMetadataItems.add(item);
ArrayList<Cite> cites = new ArrayList<Cite>();
Cite cite = new Cite();
cite.setCiteStr("MyCite");
cites.add(cite);
item.setCitesAffected(cites);
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(rtSuperQuickMetadata, System.out);
這會將結果輸出到System.out
。 你可以把它放在一個文件中,不管你需要什么。
我已經添加了這個答案,以解決您發布的后續問題,作為對cklab給出的答案的評論 。
我有另一個問題。 為什么jaxb不會自動為對象中包含的列表分配內存。 為什么我們需要在構造函數中為它分配內存?
你不需要,見下文。
在解組這些項時,以下內容不會保存到元數據對象中。 12我需要添加另一個元素才能生成?
見下面的映射。
RtSuperQuickMetadata
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "contentFiles")
public class RtSuperQuickMetadata {
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
@XmlElement(name="contentFile")
public List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() {
return rtSuperQuickMetadataItems;
}
public void setRtSuperQuickMetadataItems(
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems) {
this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems;
}
}
RtSuperQuickMetadataItem
import java.util.List;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder={"contentFileName", "title", "sourcePublicationDate", "alternateDocNumbers", "citesAffected"})
public class RtSuperQuickMetadataItem {
private String contentFileName;
private String title;
private String sourcePublicationDate;
private List<AlternateDocNumber> alternateDocNumbers;
private List<Cite> citesAffected;
public List<AlternateDocNumber> getAlternateDocNumbers() {
return alternateDocNumbers;
}
public List<Cite> getCitesAffected() {
return citesAffected;
}
public String getContentFileName() {
return contentFileName;
}
public String getSourcePublicationDate() {
return sourcePublicationDate;
}
public String getTitle() {
return title;
}
public void setAlternateDocNumbers(
List<AlternateDocNumber> alternateDocNumbers) {
this.alternateDocNumbers = alternateDocNumbers;
}
public void setCitesAffected(List<Cite> citesAffected) {
this.citesAffected = citesAffected;
}
public void setContentFileName(String contentFileName) {
this.contentFileName = contentFileName;
}
public void setSourcePublicationDate(String sourcePublicationDate) {
this.sourcePublicationDate = sourcePublicationDate;
}
public void setTitle(String title) {
this.title = title;
}
}
AlternateDocNumber
class AlternateDocNumber {
private String alternateDocNumber;
public String getAlternateDocNumber() {
return alternateDocNumber;
}
public void setAlternateDocNumber(String alternateDocNumber) {
this.alternateDocNumber = alternateDocNumber;
}
}
引用
class Cite {
private String cite;
public String getCite() {
return cite;
}
public void setCite(String cite) {
this.cite = cite;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.