I have a application JSON -> XML converter. This application will take a List of events that are converted to XML one by one. Before conversion, the header for the final XML will be created using the start method, and later converted events are added to xmlEventWriter one-by-one, and finally after all the conversion the closing tags are added to the XML using end method.

I am facing an issue during the closing of tags and running into the error:

javax.xml.stream.XMLStreamException: No open start element, when trying to write end element

As per my understanding, everything is correct but still facing the issue don't know why.

Following is the class that will create the header body and closure tags in XML:



public class EventXMLStreamCollector implements EventsCollector<OutputStream> {

    private final OutputStream stream;
    private final XMLEventWriter xmlEventWriter;
    private final XMLEventFactory events;

    public EventXMLStreamCollector(OutputStream stream) {
        this.stream = stream;
        try {
            xmlEventWriter = XMLOutputFactory.newInstance().createXMLEventWriter(stream);
            events = XMLEventFactory.newInstance();
        } catch (XMLStreamException e) {
            throw new EventFormatConversionException("Error occurred during the creation of XMLEventWriter : " + e);
        }

    }

    public void collect(Object event) {
        System.out.println("COLLECT START");
        try {
            XMLEventReader xer = new EventReaderDelegate(XMLInputFactory.newInstance().createXMLEventReader(new StringReader(event.toString()))) {
                @Override
                public boolean hasNext() {
                    if (!super.hasNext())
                        return false;
                    try {
                        return !super.peek().isEndDocument();
                    } catch (XMLStreamException ignored) {
                        return true;
                    }
                }
            };
            if (xer.peek().isStartDocument()) {
                xer.nextEvent();
                xmlEventWriter.add(xer);
            }
        } catch (XMLStreamException e) {
            throw new EventFormatConversionException("Error occurred during the addition of events to XMLEventWriter: " + e);
        }
        System.out.println("COLLECT END");
    }

    @Override
    public OutputStream get() {
        return stream;
    }

    @Override
    public void start(Map<String, String> context) {
        System.out.println("START START");
        try {
            xmlEventWriter.add(events.createStartDocument());
            xmlEventWriter.add(events.createStartElement(new QName("doc:Document"), null, null));
            xmlEventWriter.add(events.createNamespace("doc", "urn:one"));
            xmlEventWriter.add(events.createNamespace("xsi", "http://www.w3.org/2001/XMLSchem-instance"));
            xmlEventWriter.add(events.createNamespace("cbvmda", "urn:two"));
            
            for (Map.Entry<String, String> stringStringEntry : context.entrySet()) {
                xmlEventWriter.add(events.createAttribute(stringStringEntry.getKey(), stringStringEntry.getValue()));
            }

            xmlEventWriter.add(events.createStartElement(new QName("Body"), null, null));
            xmlEventWriter.add(events.createStartElement(new QName("EventList"), null, null));
        } catch (XMLStreamException e) {
            throw new EventFormatConversionException("Error occurred during the creation of final XML file header information " + e);
        }
        System.out.println("START END");
    }

    @Override
    public void end() {
        System.out.println("END START");
        try {
            System.out.println(xmlEventWriter.toString());
            xmlEventWriter.add(events.createEndElement(new QName("EventList"), null));
            xmlEventWriter.add(events.createEndElement(new QName("Body"), null));
            xmlEventWriter.add(events.createEndElement(new QName("doc:Document"), null));
            xmlEventWriter.add(events.createEndDocument());
            xmlEventWriter.close();
        } catch (XMLStreamException e) {
            throw new EventFormatConversionException("Error occurred during the closing xmlEventWriter:" + e);
        }
        System.out.println("END END");
    }

    @Override
    public void collectSingleEvent(Object event) {
        try {
            XMLEventReader xer = XMLInputFactory.newInstance().createXMLEventReader(new StringReader(event.toString()));
            if (xer.peek().isStartDocument()) {
                xer.nextEvent();
            }
            xmlEventWriter.add(xer);
        } catch (XMLStreamException e) {
            System.out.println("ADDED : " + e.getMessage());
            throw new EventFormatConversionException("Error occurred during the addition of events to XMLEventWriter: " + e);
        }
    }
}

I am getting the error for this line:

xmlEventWriter.add(events.createEndElement(new QName("Body"), null));

I am not sure why I am getting this error. I am opening the Body tag and then trying to close it. I am sure that the flow is correct, I am calling start, collect, and then finally end. Following the output I am getting:

START START
START END
COLLECT START
COLLECT END
END START

I am not getting END END because of the error I am getting for the closing of Body tag. Can someone please help me understand this issue and provide some workaround and help.

0

There are 0 best solutions below