Отмена сопоставления со сложным типом

#java #jaxb

#java #jaxb

Вопрос:

У меня возникли проблемы с отменой сопоставления XML, который представляет счет-фактуру в этой форме:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Body>
        <Response xmlns="Lamp">
            <Result>
                <Title>The Title</Title>
                <Lines>
                    <anyType xsi:type="InvoiceLine">
                        <Name>Name One</Name>
                        <Quantity>1.0000</Quantity>
                    </anyType>
                    <anyType xsi:type="InvoiceLine">
                        <Name>Name Two</Name>
                        <Quantity>2.0000</Quantity>
                    </anyType>
                </Lines>
            </Result>
        </Response>
    </soap:Body>
</soap:Envelope>
 

Класс Invoice:

 @XmlAccessorType(XmlAccessType.FIELD)
public class Invoice {
    public String Title;
    public List<InvoiceLine> Lines;
}
 

Класс InvoiceLine:

 @XmlAccessorType(XmlAccessType.FIELD)
public class InvoiceLine extends anyType {
    public String Name;
    public float quantity;
}
 

И абстрактный класс для любого типа:

 public abstract class anyType {}
 

Это код, который я использую для выполнения отмены сопоставления:

 public static void main(String[] args) throws Exception {

    InputStream is = new FileInputStream("input.xml");

    XMLInputFactory xif = XMLInputFactory.newFactory();
    XMLStreamReader xsr = xif.createXMLStreamReader(is);

    xsr.nextTag();
    while(!xsr.getLocalName().equals("Result")) {
        xsr.nextTag();
    }

    JAXBContext jc = JAXBContext.newInstance(Invoice.class, InvoiceLine.class);
    javax.xml.bind.Unmarshaller unmarshaller = jc.createUnmarshaller();

    JAXBElement<Invoice> jb = unmarshaller.unmarshal(xsr, Invoice.class);
    xsr.close();

    System.out.println(jb.getValue());

}
 

Проблема в том, что список строк содержит только 1 запись с именем = null и количеством = 0.0.

— Редактировать:

Я только что попытался добавить аннотации XmlElement и XmlElementWrapper к обоим классам, единственное изменение заключается в том, что список строк не содержит элементов.

Измененный счет-фактура:

 @XmlAccessorType(XmlAccessType.FIELD)
public class Invoice {
    @XmlElement(name = "Title")
    public String Title;
    @XmlElement(name = "anyType")
    @XmlElementWrapper(name = "Lines")
    public List<InvoiceLine> Lines;
 }
 

Измененная строка InvoiceLine:

 @XmlAccessorType(XmlAccessType.FIELD)
public class InvoiceLine extends anyType {
    @XmlElement(name = "Name")
    public String Name;
    @XmlElement(name = "Quantity")
    public float Quantity;
}
 

— Редактировать:
Я только что попытался сделать атрибуты строчными, но все равно безуспешно.

Комментарии:

1. Вы пробовали явно аннотировать поля своего класса? Я думаю, что есть некоторая проблема с именами, начинающимися с прописных букв, и с тем, как интерпретатор JAXB обрабатывает их.

2. Спасибо за ответ, я обновил свой вопрос вашим предложением (я также пробовал его без аннотации XmlElementWrapper). Единственное изменение — теперь список строк содержит 0 элементов, а не один пустой.