Я не понимаю, зачем нам нужны 2 парсера XML в PHP.
Может кто-нибудь объяснить разницу между этими двумя?
Я не понимаю, зачем нам нужны 2 парсера XML в PHP.
Может кто-нибудь объяснить разницу между этими двумя?
В двух словах:
SimpleXml
$root->foo->bar['attribute']
DOM
Оба они основаны на 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 - это только те, которые анализируют документ в древовидной структуре. Остальные - это синтаксические анализаторы/читатели/писатели, основанные на событиях или событиях.
Также см. мой ответ на
Я собираюсь сделать кратчайший возможный ответ, чтобы новички могли легко снять его. Я также немного упрощаю вещи ради краткости. Перейти к концу этого ответа для завышенной версии 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-контента. На самом деле выбор легко, потому что с самого начала нет выбора:
Как отмечали другие, расширения 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 может быть более уместным.
SimpleXML - это, как указано в названии, простой синтаксический анализатор для содержимого XML и ничего больше. Вы не можете разобрать, допустим, стандартный html-контент. Это легко и быстро, и, следовательно, отличный инструмент для создания простых приложений.
Расширение DOM, с другой стороны, намного мощнее. Это позволяет вам анализировать практически любой документ DOM, включая html, xhtml, xml. Это позволяет вам открывать, писать и даже исправлять код вывода, поддерживает xpath и общую манипуляцию. Поэтому его использование намного сложнее, потому что библиотека довольно сложная, и это делает ее идеальным инструментом для больших проектов, где требуется тяжелая манипуляция данными.
Надеюсь, что ответит на ваш вопрос:)
Самое большое различие между двумя библиотеками состоит в том, что 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 этого не делают. Они предлагают отливку в массив, но только как любой другой объект (общедоступные свойства как ключи/значения).
SimpleXMLElement
в DOM и наоборот. Вы узнаете больше о DOM и о том, как использовать расширение, чтобы делать то, что вам не удалось (или не удалось выяснить) с SimpleXMLElement
.Вы можете получать удовольствие от обоих расширений, и я думаю, вы должны знать оба. Чем больше, тем лучше. Все расширения на основе libxml в PHP - это очень хорошие и мощные расширения. И на Stackoverflow под php есть хорошая традиция хорошо освещать эти библиотеки, а также подробную информацию.