В чем разница между расширениями DOM PHP и SimpleXML?

Я не понимаю, зачем нам нужны 2 парсера XML в PHP.

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

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

SimpleXml

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

DOM

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

Оба они основаны на libxml, и на некоторые из них могут влиять функции libxml


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

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

Но это всего лишь мой 2c. Составьте свой разум 🙂


В сиднейте нет двух парсеров, но еще пара в PHP . SimpleXml и DOM – это только те, которые анализируют документ в древовидной структуре. Остальные – это синтаксические анализаторы / читатели / писатели.

Также см. Мой ответ на

  • Лучший XML-парсер для PHP

Я сделаю кратчайший возможный ответ, чтобы новички могли легко снять его. Я также немного упрощаю вещи ради краткости. Перейти к концу этого ответа для завышенной версии 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 очень сложный, но использует очень мало памяти. Очень ситуационная.

Как отмечали другие, расширения 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. Для более крупных документов может быть более подходящим XML – простейший XML-анализатор или «основанный на событиях» XML-анализатор .

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

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

Надеюсь это ответит на твой вопрос 🙂

Какие 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 также абстрагирует доступ к спискам SimpleXMLElement и списков атрибутов, а также обеспечивает обход через имена элементов (доступ к свойствам), атрибуты (доступ к массиву), а также возможность Traversable итерации его «собственных» детей (элементы или атрибуты) и предлагая доступ к именам через методы children() и attributes() .

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

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

  • Как отличить объекты SimpleXML от элемента и атрибута?

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

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

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

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

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

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

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