STAX для изменения вложенного XML с условиями и обратной записи для огромного XML — около 6 ГБ.

Я новичок в Java и работаю над кодом для распаковки zip-файла, содержащего около 100 000 XML-файлов, а затем объединения этих файлов в 1 XML-файл, чтобы я мог обрабатывать один файл вместо загрузки этих многих файлов. Я разархивировал файл и объединил его в 1 файл и проанализировал с помощью синтаксического анализатора DOM, но теперь мне нужно изменить этот объединенный XML-файл, а затем записать его обратно в 1 файл. Я могу сделать это с помощью синтаксического анализатора DOM и StringBuilder, но похоже, что StringBuilder не может обработать этот большой файл, поскольку он дает ошибку пространства кучи java.

В ходе дальнейших исследований я понял, что синтаксический анализатор STAX может хорошо подходить для обработки больших файлов с большей производительностью.

Я просматривал несколько статей и руководств, но пока не смог написать код, который удовлетворил бы мои требования. Итак, мой XML имеет несколько тегов, после слияния у меня есть примерно такая структура:

<Items>
   <Item >
      <Tag1>
</Tag1>
         <Tag2>
</Tag2>
            <Images>
               <Image>
                  <width>200</width>
                  <height>200</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
               <Image>
                  <width>400</width>
                  <height>600</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
            </Images>
   </Item>
   <Item >
      <Tag1>
</Tag1>
         <Tag2>
</Tag2>
            <Images>
               <Image>
                  <width>100</width>
                  <height>400</height>
                  <url>abc.com</url>
                  <action>update</action>
               </Image>
               <Image>
                  <width>400</width>
                  <height>200</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
            </Images>
   </Item>
</Items>

Мое требование состоит в том, чтобы проверить, превышает ли ширина и высота тега изображения некоторое значение, а затем взять только тег изображения, иначе удалите его из раздела «Изображения». Точно так же некоторые другие теги, которые мне нужно будет удалить из файла, и как только вся обработка будет завершена, верните весь XML-файл обратно с изменениями.

Я прочитал много статей по реализации STAX, но не смог понять, как получить доступ к тегу изображения, который является своего рода правнуком корневого тега «Items».


person Vaishali Ahlawat    schedule 05.05.2021    source источник


Ответы (1)


Использовать потоковую передачу XSLT 3.0 очень просто:

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="Image">
  <xsl:variable name="image" select="copy-of(.)"/>
  <xsl:sequence select="$image[width*height gt 100000]"/>
</xsl:template>

Конечно, здесь можно использовать любой предикат по ширине и высоте. Таблица стилей выводит изображение тогда и только тогда, когда предикат истинен.

Однако, если у вас есть 6 ГБ XML, распределенных по файлам 100 КБ, я не уверен, почему вы объединяете их перед обработкой. Это потребует гораздо больше ресурсов памяти, чем обработка их по отдельности (что также можно сделать с помощью нескольких строк кода XSLT).

person Michael Kay    schedule 05.05.2021
comment
Спасибо, Майкл, я не уверен в XSLT, сейчас изучаю это. Что касается объединения файлов, моя система, которая использует эти файлы, должна сначала загрузить все отдельные файлы, а затем начать их обработку, поэтому я хочу, чтобы система сохраняла некоторую производительность, не загружая файлы по отдельности, а просто загружая 1 большой файл, и в том же процессе я хочу также укоротить файл, удалив ненужные теги. - person Vaishali Ahlawat; 06.05.2021
comment
Я не могу сохранить шаблон XSLT на жестком диске, так как буду развертывать этот код как плагин во внешнем приложении. Я пытаюсь создать шаблон в папке File в моем проекте Eclipse. Я создаю файл с расширением .xsl, это правильно? На самом деле я получаю сообщение об ошибке в первой строке внутри шаблона: В этой строке найдено несколько аннотаций: - Префикс xsl для элемента xsl:mode не привязан. - Нет грамматических ограничений (DTD или XML-схема). Я не придерживаюсь правильного подхода? Я очень новичок во всем этом, пожалуйста, извините меня, если это так глупо спрашивать. - person Vaishali Ahlawat; 06.05.2021
comment
У вас возникли проблемы с XSLT для новичков, и если вы не можете решить их, следуя стандартным руководствам, задайте отдельный вопрос. В любом учебнике по XSLT будет показана базовая шаблонная структура таблицы стилей XSLT, включая объявление пространства имен для префикса xsl. Обратите внимание, что для этой таблицы стилей требуется XSLT 3.0, который по умолчанию не поддерживается в Eclipse; Я думаю, что единственный доступный в настоящее время процессор, поддерживающий возможности потоковой передачи, — это Saxon-EE. - person Michael Kay; 06.05.2021
comment
, Спасибо за указания, но сейчас у меня крайний срок, и, поскольку XSLT для меня совершенно новый, я найду время, чтобы пройти его. Также не уверен, что мое приложение будет синхронизировано с тем же. Пока я прохожу это, могут ли быть какие-то предложения по STAX, так как я уже работаю в этом направлении, может быть, мне будет немного проще и быстрее сделать это. - person Vaishali Ahlawat; 08.05.2021
comment
Мы все знали, что было бы неплохо потратить время на изучение инструмента, который лучше подходит для работы, чем тот, который мы уже знаем, поэтому я вам сочувствую. Но я не буду писать для вас 50 строк кода, когда могу сделать это за 5, извините! - person Michael Kay; 09.05.2021
comment
Спасибо @Майкл Кей! просто у меня крайний срок, и начинать все с нуля займет у меня время. Я также не уверен, что мое внешнее приложение будет поддерживать все это, хотя я параллельно работаю над интеграцией SAXON EE в Eclipse (если возможно, не уверен), - person Vaishali Ahlawat; 09.05.2021
comment
Я начал с интеграции XSLT, но получил ошибку потоковой передачи, которая не поддерживает ее, я отправил еще один вопрос о том же, было бы очень полезно, если бы вы могли дать некоторые указания, спасибо stackoverflow.com/questions/67487745/< /а> - person Vaishali Ahlawat; 11.05.2021