Java 8 - разделение огромного XML-файла с использованием Stax дает неожиданные результаты

При разделении огромного XML-файла я увидел очень хорошее решение с использованием Stax и Transformer.transform(). Хорошо, НО я вижу, что некоторые теги потерялись. Почему?

XML-файл с именем... дает следующий результат. В случаях EVENT тег элемента опускается.

Element: <?xml version="1.0" encoding="UTF-8"?><car><name>car1</name></car>
Element: <?xml version="1.0" encoding="UTF-8"?><name>car2</name>
Element: <?xml version="1.0" encoding="UTF-8"?><car><name>car3</name></car>
Element: <?xml version="1.0" encoding="UTF-8"?><name>car4</name>

Как получить нужные элементы? Это связано с тем, что transform(s, r) мешает чтению входного потока?

Это мой код (который я видел во многих местах, таких как этот). Нет никаких изменений при использовании StringReader или FileReader.

Я ожидал этого: цикл { переход к начальному тегу; получить доступ к этому элементу } Что я вижу: 1-й: элемент + 2-й: части элемента + повтор.

String testCars = "<root><car><name>car1</name></car><car><name>car2</name></car><car><name>car3</name></car><car><name>car4</name></car></root>";
String element = "car";
try {
    XMLInputFactory factory = XMLInputFactory.newInstance();
    XMLStreamReader streamReader = factory.createXMLStreamReader(new StringReader(testCars));
    streamReader.nextTag();
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    while(streamReader.nextTag() == XMLStreamConstants.START_ELEMENT) {
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            t.transform(new StAXSource(streamReader), result);
            System.out.println("Element: " + writer.toString());
    }
} catch (Exception e) { ... }

person tm1701    schedule 26.04.2019    source источник
comment
Как вы думаете, в какой позиции находится streamReader после вызова transform(...) и почему вы так считаете, то есть где вы видели задокументированное такое поведение?   -  person Andreas    schedule 26.04.2019
comment
Этот комментарий должен был быть ответом на мой комментарий? Я не спрашивал, что произойдет, если вы не позвоните transform(...). Я спросил, как вы ожидаете, что читатель будет после звонка, и я спросил, почему вы ожидаете этого, учитывая, что я не могу показаться найти какую-либо документацию, указывающую, что это будет, т.е. она кажется неуказанной. --- код показан как решение в большем количестве мест Например, где и как вы узнаете, что он действителен. То, что вы можете найти это в Интернете, не означает, что это правда.   -  person Andreas    schedule 26.04.2019
comment
Хорошо, я обновил образец ссылки. Этот образец также упоминается в других местах. Что я ожидал? Есть и сейчас в ответе.   -  person tm1701    schedule 26.04.2019
comment
Вы читали последний комментарий к предоставленной вами ссылке?   -  person Andreas    schedule 27.04.2019
comment
ВЕЛИКОЛЕПНО! Можете ли вы добавить это как ответ?   -  person tm1701    schedule 27.04.2019


Ответы (1)


Благодаря Андреасу, это решение:

String testCars = "<root><car><name>car1</name></car><other><something>Unknown</something></other><car><name>car2</name></car></root>";
XMLInputFactory factory = XMLInputFactory.newInstance();
try {
    XMLStreamReader streamReader = factory.createXMLStreamReader(new StringReader(testCars));
    streamReader.nextTag();
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    streamReader.nextTag();
    while ( streamReader.isStartElement() ||
          ( ! streamReader.hasNext() && streamReader.nextTag() == XMLStreamConstants.START_ELEMENT)) {
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        t.transform(new StAXSource(streamReader), result);
        System.out.println( "XmlElement: " + writer.toString());
    }
} catch (Exception e) { ... }

Вход:

<root>
  <car>
    <name>car1</name>
  </car>
  <other>
    <something>Unknown</something>
  </other>
  <car>
    <name>car2</name>
  </car>
</root>

Выход:

XmlElement: <?xml version="1.0" encoding="UTF-8"?><car><name>car1</name></car>
XmlElement: <?xml version="1.0" encoding="UTF-8"?><other><something>Unknown</something></other>
XmlElement: <?xml version="1.0" encoding="UTF-8"?><car><name>car2</name></car>
person tm1701    schedule 27.04.2019