Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

SimpleXml

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

DOM

  • для любого XML UseCase у вас может быть
  • представляет собой реализацию W3C DOM API (найдена на многих языках)
  • различает различные типы node (больше контроля)
  • гораздо более подробный из-за явного 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 ничего не сделает. Теперь, конечно, правильно, что вы не можете добавить атрибут к атрибуту Node, но точка такова, что атрибут node не будет раскрывать этот метод в первую очередь.

Но это только мой 2c. Составьте свой разум:)


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

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

Ответ 2

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


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

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

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


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

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

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

TL; DR

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ниже приведена таблица сравнения, содержащая те типы DOMNode, которые действительно полезны, если речь идет о XML (полезные типы node). Ваш пробег может варьироваться, например. когда вам нужно иметь дело с 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, так же как и магии, как и ограниченного.

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

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

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

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

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

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

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

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