当列表节点名称和项目节点名称相同时,将XML映射到模型

时间:2014-04-22 13:24:10

标签: java xml jaxb

我正在为API编写客户端,我正在尝试将顶部响应映射到我的模型: https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md

这是我的InvoiceMessageCollection

@XmlRootElement(name = "invoice-message")
@XmlAccessorType(XmlAccessType.NONE)
public class InvoiceMessageCollection
        implements Iterable<InvoiceMessage>
{
    @XmlElement(name = "invoice-message")
    private List<InvoiceMessage> list = new ArrayList<InvoiceMessage>();

    public List<InvoiceMessage> getList()
    {
        return list;
    }

    public void setList(List<InvoiceMessage> list)
    {
        this.list = list;
    }

    public static InvoiceMessageCollection fromInputStream(final InputStream xml)
            throws HarvestClientException
    {
        try
        {
            JAXBContext context = JAXBContext.newInstance(InvoiceMessageCollection.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            return (InvoiceMessageCollection) unmarshaller.unmarshal(xml);
        }
        catch (Exception e)
        {
            throw new HarvestClientException("Unable to parse XML into InvoiceItemCategory.", e);
        }
    }

    @Override
    public Iterator<InvoiceMessage> iterator()
    {
        return this.list.iterator();
    }
}

问题是列表和项目都具有相同的节点名称。这显然是他们的API中的一个错误,因为这是唯一一个具有相同名称的调用,但仍然 - 有没有办法解决这个问题并且仍然使用JAXB?

由于InvoiceMessage无法强制转换为InvoiceMessageCollection,因此会在return (InvoiceMessageCollection) unmarshaller.unmarshal(xml);上抛出实际异常。

Exception in thread "main" com.enonic.harvestclient.exceptions.HarvestClientException: Unable to parse XML into InvoiceItemCategory.
        at com.enonic.harvestclient.models.InvoiceMessageCollection.fromInputStream(InvoiceMessageCollection.java:45)
        at com.enonic.harvestclient.DefaultHarvestClient.getInvoiceMessages(DefaultHarvestClient.java:315)
        at com.enonic.harvestclient.Testing.main(Testing.java:22)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
        Caused by: java.lang.ClassCastException: com.enonic.harvestclient.models.InvoiceMessage cannot be cast to com.enonic.harvestclient.models.InvoiceMessageCollection
        at com.enonic.harvestclient.models.InvoiceMessageCollection.fromInputStream(InvoiceMessageCollection.java:41)
        ... 7 more

1 个答案:

答案 0 :(得分:1)

invoice-message@XmlRootElement具有相同的元素名称@XmlElement不会导致JAXB出现任何问题。例外情况似乎在您自己的代码中。

Caused by: java.lang.ClassCastException: com.enonic.harvestclient.models.InvoiceMessage cannot be cast to com.enonic.harvestclient.models.InvoiceMessageCollection
        at com.enonic.harvestclient.models.InvoiceMessageCollection.fromInputStream(InvoiceMessageCollection.java:41)
        ... 7 more

更新

  

我的InvoiceMessage模型还有@XmlRootElement(name =   &#34; invoice-message&#34;)因为需要单个发票消息。   这使得JAXB认为返回的列表实际上是一条消息。

你无法做到这一点。不应使用InvoiceMessageCollection注释@XmlRootElement,而应使用其中一个采用Class参数的unmarshal方法。

 InvoiceMessageCollection imc = unmarshaller.unmarshal(xml, InvoiceMessageCollection.class).getValue();
相关问题