Исключение XMLStreamWriter: атрибут, не связанный ни с одним элементом

#java #xmlstreamwriter

#java #xmlstreamwriter

Вопрос:

Я получаю это исключение:

 javax.xml.stream.XMLStreamException: Attribute not associated with any element
    at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeAttribute(Unknown Source)
    at de.dhbw.horb.routePlanner.parser.GraphDataParser$2.run(GraphDataParser.java:136)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)*
 

Из моего кода ниже.
Я просто не понимаю, откуда он берется.

 public void writeEdgeXML() throws XMLStreamException {

    final long[] idCount = new long[1];

    XMLOutputFactory factory = XMLOutputFactory.newInstance();

    try {
        final XMLStreamWriter writer = factory
                .createXMLStreamWriter(new FileOutputStream(
                        GraphDataConstants.CONST_XML_EDGE), "UTF-8");

        writer.writeStartDocument("UTF-8", "1.0");

        while (graphSR.hasNext()) {
            if (graphSR.nextStartElement() amp;amp; graphSR.isWay()) {

                final Way nextWay = getWay(null);

                Controller.executor.getExecutor().submit(new Runnable() {

                    @Override
                    public void run() {

                        while (nextWay != null amp;amp; nextWay.hasEdge()) {

                            try {
                                idCount[0]  ;
                                Edge e = nextWay.removeFirstEdge();
                                writer.writeStartElement(GraphDataConstants.CONST_EDGE);
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_ID,
                                        String.valueOf(idCount[0]));
                                writer.writeEmptyElement(GraphDataConstants.CONST_EDGE_NODE);
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_ID,
                                        String.valueOf(e.getStartNode()
                                                .getID()));
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_LATITUDE,
                                        String.valueOf(e.getStartNode()
                                                .getLatitude()));
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_LONGITUDE,
                                        String.valueOf(e.getStartNode()
                                                .getLongitude()));                                  

                                writer.writeEndElement();
                                writer.flush();

                            } catch  (XMLStreamException e) {
                                   e.printStackTrace();
                            }

                        }
                    }
                });
            }
        }
 

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

1. в de.dhbw.horb.routePlanner.parser. GraphDataParser$2.выполнить(GraphDataParser.java:136)

2. Вероятно, вы не сможете записать атрибут после writeEmptyElement . Должны ли атрибуты относиться к пустому элементу или к окружающему элементу?

3. @rahul pasricha::D спасибо, что рассказали мне, что я могу прочитать в исключении. Я могу понять исключения. Проблема в том, что это не имеет для меня никакого смысла.

4. @JimGarrison: это должно выглядеть так: <идентификатор ребра = «1»><идентификатор узла = «324» широта =»59.3″ длина =»6.0″/><идентификатор узла = «325» широта =»59.4″ длина =»6.1″/> </edge>

5. Я только что попробовал … мой предыдущий комментарий был неверным, вы можете добавить атрибуты к пустому элементу.

Ответ №1:

XMLStreamWriter не является потокобезопасным.

Вы создаете один XMLStreamWriter , а затем пытаетесь использовать его для записи элементов в несколько потоков одновременно. Это не гарантирует, что будет работать вообще, и если это произойдет, созданные вами элементы и атрибуты не обязательно окажутся там, где вы их ожидали. Я подозреваю, что ошибка связана с условием гонки в соответствии с

 Thread 1             Thread 2
--------             --------
1) emptyElement
2) attribute
                     3) emptyElement
4) endElement
                     5) attribute (BANG!)
 

Вам необходимо сериализовать все записи XML в один поток.

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

1. Это тоже мое предположение. Но как сериализовать в один поток? Разве это не замедляет его?

2. @besnep на самом деле у вас нет выбора. Если removeFirstEdge бы это была дорогостоящая операция, тогда могло бы иметь смысл иметь несколько потоков и просто синхронизировать бит записи XML от начала до конца пограничного элемента, но этот бит определенно должен быть однопоточным. Если removeFirstEdge это дешево, то вы могли бы также выполнить весь процесс в одном потоке и избавиться от накладных расходов на переключение контекста.