В чем разница между PHP-расширениями DOM и SimpleXML? - PullRequest
52 голосов
/ 26 января 2011

Я не понимаю, зачем нам два PHP-анализатора в PHP.

Может кто-нибудь объяснить разницу между этими двумя?

Ответы [ 5 ]

96 голосов
/ 26 января 2011

В двух словах:

SimpleXml

  • для простого XML и / или простых вариантов использования
  • ограниченный API для работы с узлами (например, не может программировать на интерфейс слишком много)
  • все узлы одного типа (узел элемента совпадает с узлом атрибута)
  • узлы магически доступны, например, $root->foo->bar['attribute']

ДОМ

  • для любого XML UseCase, который у вас может быть
  • является реализацией DOM API W3C (реализовано на многих языках)
  • различает различные типы узлов (больше контроля)
  • гораздо более многословно из-за явного API (может кодировать интерфейс)
  • может разобрать битый HTML
  • позволяет использовать функции PHP в запросах XPath

Оба они основаны на libxml и могут в некоторой степени зависеть от функций libxml


Лично , я не слишком люблю SimpleXml. Это потому, что мне не нравится неявный доступ к узлам, например $foo->bar[1]->baz['attribute']. Он связывает фактическую структуру XML с интерфейсом программирования. Тип «один узел для всего» также несколько не интуитивен, потому что поведение SimpleXmlElement волшебным образом меняется в зависимости от его содержимого.

Например, если у вас есть <foo bar="1"/>, дамп объекта /foo/@bar будет идентичен дампу /foo, но выполнение эха из них выведет разные результаты. Более того, поскольку оба они являются элементами SimpleXml, вы можете вызывать для них одни и те же методы, но они будут применяться только тогда, когда SimpleXmlElement это поддерживает, например, попытка сделать $el->addAttribute('foo', 'bar') на первом SimpleXmlElement ничего не даст. Теперь, конечно, правильно, что вы не можете добавить атрибут к узлу атрибута, но дело в том, что узел атрибута не будет представлять этот метод в первую очередь.

Но это только мой 2с. Решайся :)


На sidenote не существует двух парсеров, но еще пара в PHP . SimpleXml и DOM - это всего лишь два, которые анализируют документ в древовидную структуру. Остальные парсеры / читатели / писатели на основе событий или событий.

Также смотрите мой ответ на

39 голосов
/ 27 января 2011

Я собираюсь сделать кратчайший возможный ответ, чтобы новички могли легко его убрать. Я также немного упрощаю вещи ради краткости. Перейти к концу ответа для завышенной версии TL; DR.


DOM и SimpleXML на самом деле не два разных синтаксических анализатора . Настоящий парсер - libxml2 , который используется внутри DOM и SimpleXML. Таким образом, DOM / SimpleXML - это всего лишь два способа использовать один и тот же синтаксический анализатор, и они обеспечивают способы преобразования одного объекта в другого .

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

DOM предлагает полноценную реализацию DOM плюс несколько нестандартных методов, таких как appendXML . Если вы привыкли манипулировать DOM в Javascript, вы найдете точно такие же методы в DOM PHP. По сути, не имеет ограничений в том, что вы можете сделать, и он даже обрабатывает HTML. Обратная сторона этого богатства функций заключается в том, что он более сложный и более подробный, чем SimpleXML.


Побочное примечание

Люди часто задаются вопросом / спрашивают, какое расширение им следует использовать для обработки своего содержимого XML или HTML. На самом деле выбор прост, потому что выбора не так много:

  • если вам нужно разобраться с HTML, у вас нет выбора: вам нужно использовать DOM
  • если вам нужно сделать что-то необычное, например, переместить узлы или добавить какой-нибудь необработанный XML, опять же у вас есть есть для использования DOM
  • если все, что вам нужно сделать, это прочитать и / или написать какой-то базовый XML (например, обмен данными с XML-службой или чтение RSS-канала), то вы можете использовать любой из них. или оба .
  • если ваш XML-документ настолько велик, что не помещается в памяти, вы не можете использовать его и должны использовать XMLReader , который также основан на libxml2, еще более раздражает в использовании, но все равно хорошо играет с другими

TL; DR

  • SimpleXML очень прост в использовании, но подходит только для 90% случаев.
  • DOM более сложный, но может делать все.
  • XMLReader очень сложный, но использует очень мало памяти. Очень ситуативный.
3 голосов
/ 18 мая 2013

Как уже отмечали другие, расширения DOM и SimpleXML не являются строго "синтаксическими анализаторами XML", скорее они представляют собой различные интерфейсы для структуры, генерируемой базовым синтаксическим анализатором libxml2.

Интерфейс SimpleXML обрабатывает XML как сериализованную структуру данных, так же, как если бы вы обрабатывали декодированную строку JSON. Таким образом, он обеспечивает быстрый доступ к содержимому документа с акцентом на доступ к элементам по имени и чтение их атрибутов и текстового содержимого (включая автоматическое свертывание в сущностях и разделах CDATA). Он поддерживает документы, содержащие несколько пространств имен (в основном, с использованием методов children() и attributes()), и может искать документ с использованием выражения XPath. Он также включает поддержку базовых манипуляций с контентом - например, добавление или перезапись элементов или атрибутов новой строкой.

Интерфейс DOM, с другой стороны, обрабатывает XML как структурированный документ , где используемое представление столь же важно, как и представленные данные. Поэтому он предоставляет гораздо более детальный и явный доступ к различным типам «узлов», таким как сущности и разделы CDATA, а также к некоторым, которые игнорируются SimpleXML, таким как комментарии и инструкции обработки. Он также предоставляет гораздо более богатый набор функций манипуляции, позволяя вам переставлять узлы и выбирать, например, способ представления текстового содержимого. Компромисс - довольно сложный API с большим количеством классов и методов; поскольку он реализует стандартный API (изначально разработанный для манипулирования HTML в JavaScript), может быть меньше «естественного PHP», но некоторые программисты могут быть знакомы с ним из других контекстов.

Оба интерфейса требуют, чтобы весь документ анализировался в памяти, и эффективно заключали указатели в это проанализированное представление; вы можете даже переключаться между двумя оболочками с помощью simplexml_import_dom() и dom_import_simplexml(), например, чтобы добавить «отсутствующую» функцию в SimpleXML, используя функцию из DOM API. Для больших документов более подходящим может быть XMLReader или "на основе событий" XML Parser .

2 голосов
/ 10 июля 2013

Какие DOMNodes могут быть представлены SimpleXMLElement?

Самое большое различие между двумя библиотеками заключается в том, что SimpleXML в основном представляет собой один класс: SimpleXMLElement.Напротив, расширение DOM имеет много классов, большинство из которых являются подтипом DOMNode.

Таким образом, один основной вопрос при сравнении этих двух библиотек состоит в том, какой из множества классов, предлагаемых DOM, может быть представлен SimpleXMLElement в конце?

Ниже приведена таблица сравнения, содержащая те типы DOMNode, которые действительно полезны при работе с XML (полезные типы узлов).Ваш пробег может варьироваться, например, когда вам нужно иметь дело с DTD, например:

+-------------------------+----+--------------------------+-----------+
| LIBXML Constant         |  # | DOMNode Classname        | SimpleXML |
+-------------------------+----+--------------------------+-----------+
| XML_ELEMENT_NODE        |  1 | DOMElement               |    yes    |
| XML_ATTRIBUTE_NODE      |  2 | DOMAttr                  |    yes    |
| XML_TEXT_NODE           |  3 | DOMText                  |  no [1]   |
| XML_CDATA_SECTION_NODE  |  4 | DOMCharacterData         |  no [2]   |
| XML_PI_NODE             |  7 | DOMProcessingInstruction |    no     |
| XML_COMMENT_NODE        |  8 | DOMComment               |    no     |
| XML_DOCUMENT_NODE       |  9 | DOMDocument              |    no     |
| XML_DOCUMENT_FRAG_NODE  | 11 | DOMDocumentFragment      |    no     |
+-------------------------+----+--------------------------+-----------+
  • [1]: SimpleXML абстрагирует текстовые узлы как строковое значение элемента (сравните __toString).Это работает только тогда, когда элемент содержит только текст, в противном случае текстовая информация может быть потеряна.
  • [2]: каждый XML-парсер может расширять узлы CDATA при загрузке документа.SimpleXML расширяет их, когда опция LIBXML_NOCDATA используется с simplexml_load_* функциями или конструктором .(Опция работает также с DOMDocument::loadXML())

Как показывает эта таблица, SimpleXML имеет действительно ограниченные интерфейсы по сравнению с DOM.Рядом с теми, что в таблице, SimpleXMLElement также абстрагирует доступ к дочерним элементам и спискам атрибутов, а также обеспечивает обход через имена элементов (доступ к свойствам), атрибуты (доступ к массивам), а также является Traversable повторение своих "собственных" дочерних элементов (элементов или атрибутов) и предоставление доступа к пространству имен с помощью методов children() и attributes().

Пока все эти магические интерфейсы хороши, однако их нельзя изменитьрасширяя от SimpleXMLElement, так волшебство, как оно есть, настолько же ограничено, насколько это возможно.

Чтобы узнать, какой тип узла представляет объект SimpleXMLElement, см .:

Здесь DOM следует спецификации DOMDocument Core Level 1 .С этим интерфейсом вы можете выполнять практически все возможные операции с XML.Однако это только уровень 1, поэтому по сравнению с современными уровнями DOMDocument, такими как 3, он несколько ограничен для некоторых более интересных вещей.Конечно, SimpleXML и здесь проиграл.

SimpleXMLElement позволяет приводить к подтипам.Это очень особенное в PHP.DOM также допускает это, хотя это немного больше работы, и нужно выбрать более конкретный тип узла.

XPath 1.0 поддерживается обоими, результат в SimpleXML - array из SimpleXMLElements, в DOM DOMNodelist.

SimpleXMLElement поддерживает приведение к строке и массиву (json), классы DOMNode в DOM - нет.Они предлагают приведение к массиву, но только так, как это делает любой другой объект (публичные свойства в качестве ключей / значений).

Общие шаблоны использования этих двух расширений в PHP:

  • Обычно выначать использовать SimpleXMLElement.Ваш уровень знаний об XML и XPath находится на одинаково низком уровне.
  • После борьбы с магией его интерфейсов, определенный уровень разочарования рано или поздно достигается.
  • Вы обнаружите, что можете импортировать SimpleXMLElement s в DOM и наоборот.Вы узнаете больше о DOM и о том, как использовать расширение для выполнения действий, которые вы не смогли (или не смогли выяснить, как) сделать с SimpleXMLElement.
  • . Вы заметили, что можете загружать документы HTML с помощьюРасширение DOM.И неверный XML.И сделать выходное форматирование.Вещи, которые SimpleXMLElement просто не может сделать.Даже с грязными трюками.
  • Вы, вероятно, даже полностью переключитесь на расширение DOM, потому что, по крайней мере, вы знаете, что интерфейс более дифференцирован и позволяет вам что-то делать.Также вы видите выгоду в изучении DOM Level 1, потому что вы можете использовать его также в Javascript и других языках (огромное преимущество расширения DOM для многих).

Вы можете повеселиться с обоими расширениями, и я думаю, вы должны знать оба. Чем больше, тем лучше. Все расширения на основе libxml в PHP являются очень хорошими и мощными расширениями. А в Stackoverflow под тегом есть хорошая традиция хорошо освещать эти библиотеки, а также подробную информацию.

2 голосов
/ 26 января 2011

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

, с другой стороны, намного мощнее.Это позволяет анализировать практически любой документ DOM, включая html, xhtml, xml.Это позволяет вам открывать, писать и даже корректировать выходной код, поддерживает xpath и в целом больше манипуляций.Поэтому его использование намного сложнее, потому что библиотека довольно сложна, и это делает ее идеальным инструментом для больших проектов, где требуются тяжелые манипуляции с данными.

Надеюсь, что ответит на ваш вопрос:)

...