Как работает SAX парсер? - PullRequest
       51

Как работает SAX парсер?

0 голосов
/ 01 февраля 2019

Я новичок в разборе XML.При выполнении одной задачи мне нужно разобрать файл Big XML.Поэтому, пытаясь найти хорошее решение, я столкнулся с этими двумя терминами: DOM и SAX.Это два разных типа разбора XML.Я здесь немного запутался в разборе SAX.Читайте о многом, но все еще в замешательстве.

Давайте возьмем ниже XML в качестве примера

 <?xml version="1.0" encoding="UTF-8"?>
<note>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
</note>

Допустим, я просто хочу, чтобы все прочитали все теги <body> и записали в файл.

Мои сомнения:

  1. Если я сделаю это с DOM-парсером, загрузит ли он сначала все xml в память, а затем найдет тег <body> и запишет в файл?

  2. Если я сделаю это с помощью SAX-парсера, будет ли он сначала искать сам тег <body> на диске, и в тот момент, когда он его найдет, он начнет чтение с него и продолжит загрузку в память до </body>?

  3. Если 2 сомнения верны, то как происходит такое чтение?Считывает ли SAX-парсер слово за словом и какое-то время хранит это слово в памяти и проверяет, совпадает ли с тегом, который ищет код?Потому что идентификация тега может быть сделана только в памяти, но нигде я так не думаю.И продолжайте сбрасывать слова из памяти, пока не найдете выбранное совпадение или тег <body>.В тот момент, когда он его находит, он начинает хранить все слова в памяти, пока не найдет </body>.

ПРАВИЛЬНО?
Пожалуйста, поправьте меня ..!

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Анализатор DOM загружает весь XML-документ в память и делает его доступным для вас через API Java.Преимущество этого подхода в том, что его просто использовать и понимать, но он не очень эффективен, потому что:

  • Парсер должен прочитать весь документ XML и сохранить его в памяти, даже если вы толькохотите получить доступ к небольшой его части.
  • Структуры данных, которые использует анализатор DOM (скорее всего, хэш-карты), являются универсальными и не оптимизированы для вашей ситуации.

Синтаксический анализатор SAX сложнее в использовании, но он потенциально более производительный.Парсер SAX ничего не хранит в памяти;вместо этого он вызывает код, который вы предоставляете для обработки каждого элемента XML, с которым он сталкивается.В вашем случае он перезвонит вам и скажет "Я нашел !"тогда "Я нашел !"и т. д. То, что вы будете делать с этими событиями, зависит от вас, но, как правило, вы либо создаете некоторые пользовательские объекты Java в памяти, либо генерируете поток вывода.

0 голосов
/ 01 февраля 2019

StAX (или парсеры pull) будут работать лучше для описанного вами варианта использования.DOM читает весь документ, парсеры SAX генерируют события, которые вам нужно обработать, они ничего не записывают в память (кроме своих внутренних).С SAX вам нужно написать обработчик контента, который реализует определенные методы , и это также подразумевает, что вам нужно поддерживать состояние потока событий.Например, первый кусок документа, который вы опубликовали, будет генерировать следующие (упрощенные) события:

startDocument
startElement(note)
startElement(Desc)
startElement(to)
characters(Tove) // might come as multiple chunks
endElement(to)
...
endDocument

, поэтому вам нужно проверить в startElement, если имя тега body (если вы хотите только body элементы, которые находятся в note -> Desc, тогда вам нужно отслеживать все элементы начала / конца) и установить флаг.В characters, если флаг имеет значение true, соберите текстовое содержимое тега (или запишите его на диск).Кроме того, в endElement флаг должен быть установлен в false, чтобы избежать сбора символов из других тегов.

...