Разупорядочение сложного вложенного XML-файла с использованием XMLStreamReader без XSD

Я пытаюсь развернуть вложенный XML-файл с помощью XMLStreamReader. Мой XML-файл выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<tns:Envelope
    xmlns:tns="http://www.w3.org/2003/05/soap-envelope-dial"
    xmlns:lmic="http://www.example.com"
    xmlns:producer="http://example1.com/"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:ns5="http://www.example.com/dial/3/0">
<tns:header>
...
...
</tns:header>
<tns:body>
<producer:Producer id="1234">
   <producer:GenParty>
     <producer:NameInfo>
        <producer:Comm>
           <producer:SuppName>DATA</producer:SuppName>
           <producer:ContractNumber>123456</producer:ContractNumber>
        </producer:Comm>
    </producer:NameInfo>
    <producer:Address>
      <Street>ABC</Street>
      <Country>DEF</Country>
       ...
       ...
    </prodcer:Address>
    <producer:Address>
      <Street>ABC</Street>
      <Country>DEF</Country>
       ...
       ...
    </prodcer:Address>
  </producer:GenParty>
</producer:Producer>
</tns:body>
</tns:emvelope>

Я создал следующие классы:

@XmlRootElement(name="Producer",namespace="http://example.com/")
@XmlAccessorType(XmlAccessType.FIELD)
Class Producer {
    private GenParty;
    // getter method of class GenParty
    // setter method of class GenParty
}

@XmlRootElement(name="GenParty")
@XmlAccessorType(XmlAccessType.FIELD)
class GenParty {
    private NameInfo;
    private List<Address> address;
    //getter of both fields
    // setter of both fields
}

и определены последующие классы.

Я использую XMLStreamReader для перехода к тегу, а затем пишу свой код демаршалера как:

JAXBContext jc = JAXBContext.newInstance(Producer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();                
Producer producer = unmarshaller.unmarshal(xsr,Producer.class).getValue();

Однако я получаю нулевое значение, установленное для объекта Producer. Есть ли что-то, что я делаю неправильно? Я мог бы разархивировать простые XML-файлы, но этот уровень вложенности создает для меня проблемы. Может ли кто-нибудь предложить легко это сделать или какие-либо изменения, которые я должен внести в свой скелет кода?

Заранее большое спасибо!


person Onkar Pathak    schedule 14.12.2017    source источник
comment
это из-за неправильного пространства имен в JAXB?   -  person Eldhose Abraham    schedule 14.12.2017
comment
В вашем XML используется пространство имен xmlns:producer="http://example1.com/", но класс Producer указывает namespace="http://example.com/"   -  person Luciano van der Veekens    schedule 14.12.2017


Ответы (1)


Немного сложно сказать, что вы делаете не так. Тем не менее, я бы предложил создать Producer в коде, а затем упорядочить и разобрать его, чтобы проверить, все ли ваши классы в порядке.

Если классы в порядке и маршалинг/демаршаллинг работает, переменная producer никогда не должна быть нулевой.

Вот пример того, как это упражнение будет выглядеть:

import com.sun.xml.internal.ws.streaming.DOMStreamReader;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

public class JAXBTester {

    public static void main(String[] args) throws JAXBException, ParserConfigurationException, IOException, SAXException {
        JAXBContext jc = JAXBContext.newInstance(Producer.class);
        Marshaller marshaller = jc.createMarshaller();
        Producer producer = createProducer();
        String producerStr = marshalproducer(marshaller, producer);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new ByteArrayInputStream(producerStr.getBytes("UTF-8")));
        XMLStreamReader xmlStreamReader = new DOMStreamReader(document);
        Producer readProducer = unmarshaller.unmarshal(xmlStreamReader, Producer.class).getValue();
        if (readProducer == null) {
            throw new IllegalStateException();
        }
    }

    private static String marshalproducer(Marshaller marshaller, Producer producer) throws JAXBException {
        StringWriter writer = new StringWriter();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(producer, writer);
        String res = writer.toString();
        System.out.println(res);
        return res;
    }

    private static Producer createProducer() {
        Producer producer = new Producer();
        GenParty genParty = new GenParty();
        producer.setGenParty(genParty);
        NameInfo nameInfo = new NameInfo();
        nameInfo.setInfo("Foo");
        genParty.setNameInfo(nameInfo);
        return producer;
    }

}

@XmlRootElement(name = "Producer", namespace = "http://example.com/")
@XmlAccessorType(XmlAccessType.FIELD)
class Producer {
    private GenParty genParty;

    public GenParty getGenParty() {
        return genParty;
    }

    public void setGenParty(GenParty genParty) {
        this.genParty = genParty;
    }
}

@XmlRootElement(name = "GenParty")
@XmlAccessorType(XmlAccessType.FIELD)
class GenParty {
    private NameInfo nameInfo;
    private List<Address> address;

    public NameInfo getNameInfo() {
        return nameInfo;
    }

    public void setNameInfo(NameInfo nameInfo) {
        this.nameInfo = nameInfo;
    }

    public List<Address> getAddress() {
        return address;
    }

    public void setAddress(List<Address> address) {
        this.address = address;
    }
}

class NameInfo {
    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

class Address {

    private String street;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

Если вы выполните этот код с Java 8, он не выдаст никаких исключений.

person gil.fernandes    schedule 14.12.2017
comment
Привет, у меня также возникли некоторые проблемы во время XmlStreamReader и JAXB Unmarshalling. Если у вас есть возможность, посмотрите на этот вопрос и выскажите свое предложение: stackoverflow.com/questions/67667516/ - person BATMAN_2008; 24.05.2021