Когда анализ XML с деревом DOM - это хорошо? - PullRequest
1 голос
/ 16 ноября 2011

Я озадачен идеей смотреть на XML через очки DOM.

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

Я обычно нахожу себя в следующих случаях:

  1. Я должен только читать XMLфайл.Я могу думать только о xpath и XML-запросах

  2. Я должен только писать.Последнее поколение любого шаблонизатора может работать лучше

  3. Я должен читать и писать XML.Это может быть:

    3.1 симптом чистой лени из-за нежелания изучать SQL и такие инструменты, как SQLite.

    3.2 Случай, когда данные приложения моделируются в виде дерева.По этой причине существуют базы данных XML.

    3.3 Случай, когда вы должны преобразовать структуру.Здесь правила XSLT

Некоторые ORM также могут помочь с пунктами 2 и 3. В пункте 3 я видел много самодельных реализаций с различными уровнями зрелости

  1. Читатьи сбросить в память.Чтение объектов и возврат к XML.Как независимые процессы
  2. Читайте, формируйте свое дерево и предоставляйте самодостаточный интерфейс для ваших объектов.Держите указатель на узел DOM и повторно используйте уже проанализированное дерево для записи изменений
  3. Как и в пункте 2, но люди знают о существовании некоторых хороших шаблонов, таких как активная запись

, нодаже на уровне 3. Я не уверен, почему нужно использовать DOM.

В каких случаях фактически реализуется анализатор DOM, основанный на наилучшем подходе к проблеме?

Ответы [ 3 ]

5 голосов
/ 16 ноября 2011

Вам понадобится объектная модель документа, если

  1. Доступ к любой части модели в любой момент должен быть возможен.
  2. Фактическая структура разметки должна быть сохранена, а не какая-то ее абстракция.

Если вам просто нужны некоторые значения из XML, вы должны использовать XPath или XQuery. Если у вас есть строгие требования к обработке ввода-вывода, вы найдете XSLT более подходящим. Если вам просто нужно один раз проанализировать XML и обработать его содержимое, тогда SAX будет лучшим выбором. Если XML используется для представления структурированных данных, и вы хотите этого, некоторая абстракция (например, то, что JAXB предлагает для Java) легче обрабатывать.

Но иногда, что нас действительно интересует, так это фактическая разметка + контент, и у нас должна быть полная модель в памяти. Как в браузере. Без представления (X) HTML-страниц в DOM манипулирование JavaScript было бы намного сложнее и, вероятно, было бы не таким быстрым.

Также помните, что DOM использовался, когда применялся мой первый пункт выше, но до этого было достаточно инструментов для обеспечения уровня абстракции. В Java люди часто использовали DOM или аналогичные решения, такие как JDOM и DOM4J, что иногда было бы проблематично для больших документов. Но с появлением и развитием JAXB предпочтительным методом работы с данными, инкапсулированными в XML, стало превращение его в гораздо более естественное представление Java.

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

РЕДАКТИРОВАТЬ: в ответ на дальнейший запрос. Имейте в виду, что, хотя я постараюсь быть максимально точным в своих объяснениях, я не являюсь специалистом в некоторых из этих вещей и не прочитал все соответствующие спецификации. Поэтому я постараюсь свести предположения к минимуму.

Давайте назовем какой-нибудь сценарий для моего первого пункта. У меня есть документ XML, который поддерживает большое количество настроек, относящихся к какому-либо приложению. Приложение в различных точках захочет получить некоторые из них. Это может произойти в любое время, а требуемая настройка может быть в любом месте документа XML. Как мне получить их из XML?

XPath определенно может быть ответом, как вы указали в своем комментарии. Но вопрос в том, на чем мы будем оценивать выражение XPath?

Одна вещь, которую вы могли бы сделать, это встроить выражение XPath в таблицу стилей XSLT и запустить ваш XML через это. Или, если доступный API XPath предлагает такую ​​возможность, просто отправьте туда поток SAX. Проблема в том, что в любом случае мы анализируем все или, по крайней мере, часть XML-документа каждый раз. Предположим, вам нужно 100 фрагментов данных из XML, и 30 из них находятся в конце документа. Это 30 раз, когда вы отправляете весь документ через анализатор, 30 раз каждый фрагмент разметки должен быть правильно интерпретирован. В плохом случае XML-документ - это файл на диске, и вы теряете свою производительность из-за чрезмерного доступа к диску.

Теперь представьте, что вместо этого мы использовали DOM. Недостатком является то, что весь XML-документ находится в памяти и потребляет некоторое количество оперативной памяти. Плюс ... весь документ XML находится в памяти! И в структурированном виде, который не требует, чтобы разметка больше не анализировалась должным образом, поскольку у нас есть объекты "element" и "attribute". Все было разжевано на съедобные куски. Если мы развернем наш XPath на этом сто раз, это 100 быстрых запросов к памяти. В частности, если реализация DOM достаточно умна, чтобы выполнить индексирование имен и значений элементов и атрибутов. Подумайте о разнице, подобной этой: запоминание структуры книги и способность быстро пролистать нужную главу для поиска чего-то, вместо того, чтобы начинать читать книгу с самого начала каждый раз просто потому, что вам нужна какая-то часть информации, которая оказывается быть в главе 10.

Тогда для второго пункта. Ваш вопрос там, как это связано с остальной частью моего объяснения. Я думаю, что лучший вариант использования - это DOM в веб-браузерах.

Предположим, вам нужна динамическая веб-страница, которая может запускать некоторый JavaScript, чтобы вы могли изменять его в браузере без перезагрузки страницы. Все хорошо, чистый материал Web 2.0. Вопрос в том, как мы это сделаем. Представьте, что мы вернулись к подходу просто иметь большую строку в памяти, которая представляет (X) HTML. Чтобы изменить его, мы должны были бы проанализировать, возможно, весь документ, внести соответствующие изменения, а затем браузер должен был бы проанализировать всю вещь и полностью перерисовать страницу, потому что он понятия не имеет, что на самом деле изменилось. , Может быть, это может быть разумно и сделать некоторые различия с оригинальным документом, чтобы обновить только соответствующие части его презентации. В любом случае, это громоздко.

Но любой современный браузер предоставляет интерфейс DOM для базового документа страницы в JavaScript. Теперь браузер не обязан на самом деле напрямую использовать этот DOM для его рендеринга, но он должен держать все, что там есть, в соответствии с тем, что вы видите на экране. Если мы подумаем об этом в шаблоне модель-представление-контроллер, который преобладает в графических интерфейсах, то DOM - это модель, представление браузера - это представление, и теперь с JavaScript у нас фактически есть контроллер. Если контроллер (скрипт) изменяет что-то в базовой модели (DOM), то представление (отображаемая страница) обновляется соответствующим образом. Так как мы вынуждены пройти через DOM, который поддерживается браузером, он будет замечать всякий раз, когда что-то меняется. Если реализация будет несколько умной, у нее будет прослушиватель, который уведомляется всякий раз, когда что-то проходит через интерфейс DOM для фактического изменения.

Видите ли, благодаря DOM наши скрипты имеют прямой доступ к любой части страницы, и, поскольку модель соответствует представлению, любые изменения могут быть быстро и эффективно распространены на отрендеренный материал, где он имеет значение.

Теперь факт остается фактом: DOM универсален и моделирует фактическую разметку. Это на самом деле не придает значения. У нас не будет некоторых «гиперссылочных» объектов для работы, у нас будут «элементы» с именем «a». И у нас не будет объекта «таблица» с записями «tablerow», у нас будут элементы с именами «table» и там элементы с именем «tr». Все это некоторый узел, такой как элемент, атрибут или текст без какого-либо значения. Было бы лучше, если бы в этом была какая-то семантика вместо того, чтобы мы понимали это. Например, как JAXB делает это в Java по сравнению с использованием DOM / JDOM / DOM4J или любым другим аналогичным решением.

Но это также его сила.Его общность позволяет нам подходить к нему единообразно.Это позволяет нам применять таблицы стилей и писать запросы на основе имен элементов.Это позволяет нам вводить новые элементы в новые версии HTML без необходимости менять DOM, поскольку у него уже есть все необходимое для представления этих элементов.DOM был стандартизирован W3C, поэтому мы не привязываемся к браузерным представлениям документов.И браузеру не нужно иметь дело с еще одним уровнем абстракции и косвенного обращения, который может нанести ущерб производительности.

В наши дни такая абстракция обычно оставляется для таких сред, как JQuery, которые вынимают некоторые детали низкого уровня.наших рук.Но в основе все еще лежит DOM, который позволяет нам делать такие вещи.Это было важно для превращения динамического HTML в реальность, еще до того, как слово «ajax» стало словом.Если бы мы хотели абстрагироваться дальше, мы бы посмотрели на новую войну браузеров, которая решает, какая модель лучше.Мы бы замедлили разработку HTML (даже больше), потому что в модель необходимо было бы включить новые вещи, в то время как DOM просто моделирует разметку и, таким образом, имеет все, что нужно.<canvas> может быть большой новой вещью, которую представил HTML 5, для браузеров которой теперь нужно добавить поддержку, но для DOM это просто еще один элемент, который называется «холст».Наш JavaScript все еще работает, так же как и наш CSS.

Итак, вы видите, DOM все еще имеет свое место и его использование.Но там, где когда-то люди часто быстро прибегали к нему для выполнения любой задачи, связанной с XML, доступные инструменты стали настолько многочисленными и хорошими, что в наши дни вы будете использовать их как последнее средство.Но это еще не выход.Возможно в ландшафте Java, но не на более низких уровнях.

Наконец, что касается выражений XQuery и FLWOR ... Я никогда не использовал XQuery, только XPath.Так что я не могу на самом деле сделать какие-то приличные выводы, не догадываясь.

Длинная напыщенная речь, но вечером я стремлюсь войти в этот беспорядочный поток сознания.Что хорошего в Stack Overflow, так это то, что теперь я могу использовать его, чтобы что-то объяснять людям, которые не воображаемы.Бьется по офису и разговаривает со стенами.

1 голос
/ 16 ноября 2011

Я очень редко решал, что DOM - это то, что мне нужно. Но это происходило время от времени.

Я потратил некоторое время на работу со средами веб-тестирования. По сути, они поглощают некоторый (X) HTML, а затем позволяют вам утверждать об этом. Естественный способ сделать это - проанализировать (X) HTML в дереве DOM, а затем проверить его. Большая часть проверки выполняется с помощью XPath, но XPath работает против DOM. Существует также определенное количество прямых манипуляций - например, чтобы проверить, что некоторые изображения на веб-странице находятся в правильном порядке, я бы написал выражение XPath, которое выбирает элементы изображения, затем зацикливал их, просматривая src и alt атрибуты каждого.

Однажды я написал обработчик сообщений JAX-WS, чтобы манипулировать пространствами имен в сообщении перед его отправкой в ​​неработающий веб-сервис (ему не нравились пространства имен по умолчанию; мне пришлось переписывать их все как префиксные пространства имен). Самый простой способ сделать это - получить сообщение в виде дерева DOM, а затем пройтись по нему, манипулируя пространствами имен каждого элемента по мере необходимости.

Недавно я работал над сценарием для настройки файлов конфигурации JBoss (я думаю, что это был, в частности, веб-развертыватель web.xml). Идея заключалась в том, что мы будем читать в файле, поставляемом с JBoss, применять некоторые модификации, а затем записывать результаты. Мы хотели выразить изменения простым и переносимым способом, поэтому мы написали скрипт Groovy для управления разобранным HTML. Это не вполне DOM, но это близко. В конце концов, оно оказалось очень многословным и неловким, поэтому вместо этого мы использовали XPath и процессор XML командной строки (XMLStarlet).

Общим фактором в этих случаях было то, что мне нужно было прочитать какой-то XML, манипулировать им каким-то умеренно сложным, зависящим от данных способом, а затем часто записывать его снова. Вот для чего хорош DOM.

Вы также можете использовать XSLT для этого, но, честно говоря, я бы предпочел просверлить дыру в моей голове.

0 голосов
/ 16 ноября 2011

Я бы добавил квалификацию к предыдущим ответам. Вероятно, существуют приложения, в которых использование DOM-подобного интерфейса навигации имеет смысл. Но не думайте, что DOM - единственный или лучший API в этой категории. В мире Java DOM довольно ужасен из-за всего его наследия (HTML, предварительные пространства имен) и из-за всего багажа, который был добавлен за эти годы. Другие подобные модели, такие как JDOM и XOM, намного чище и проще в использовании (и обычно быстрее).

...