PHP的DOM和SimpleXML扩展有什么区别?

2022-08-30 08:58:08

我无法理解为什么我们需要PHP中的2个XML解析器。

有人能解释这两者之间的区别吗?


答案 1

简而言之:

SimpleXml

  • 适用于简单的 XML 和/或简单的用例
  • 有限的API与节点一起工作(例如,不能编程到接口太多)
  • 所有节点都属于同一类型(元素节点与属性节点相同)
  • 节点是神奇地可访问的,例如$root->foo->bar['attribute']

多姆

  • 适用于您可能拥有的任何 XML 用例
  • 是 W3C DOM API 的实现(以多种语言实现)
  • 区分各种节点类型(更多控制)
  • 由于显式API(可以编码到接口)而更加冗长
  • 可以解析损坏的 HTML
  • 允许您在 XPath 查询中使用 PHP 函数

这两者都基于libxml,并且可以受到libxml函数的影响。


就个人而言,我不太喜欢SimpleXml。那是因为我不喜欢对节点的隐式访问,例如.它将实际的 XML 结构绑定到编程接口。一个节点类型的所有内容也有些不直观,因为SimpleXmlElement的行为会根据其内容而神奇地变化。$foo->bar[1]->baz['attribute']

例如,当您有 <foo bar=“1”/> /foo/@bar 的对象转储将与 /foo 的对象转储相同,但对它们进行回显将打印不同的结果。此外,由于它们都是 SimpleXml 元素,因此您可以对它们调用相同的方法,但只有当 SimpleXmlElement 支持它时,它们才会被应用,例如,尝试在第一个 SimpleXmlElement 上执行$el->addAttribute('foo', 'bar')将不执行任何操作。当然,不能将属性添加到属性节点是正确的,但关键是,属性节点首先不会公开该方法。

但这只是我的2c.下定决心:)


顺便说一,PHP中没有两个解析器,而是另外几个解析器。SimpleXml 和 DOM 只是将文档解析为树结构的两个。其他的是基于拉取或基于事件的解析器/读取器/写入器。

另请参阅我的答案


答案 2

我将尽可能提供最短的答案,以便初学者可以轻松将其带走。为了简短起见,我也稍微简化了事情。跳到该答案的末尾,了解夸大其词的 TL;DR 版本。


DOM 和 SimpleXML 实际上并不是两个不同的解析器。真正的解析器是libxml2,它由DOM和SimpleXML内部使用。因此,DOM / SimpleXML只是使用同一个解析器的两种方法,它们提供了将一个对象转换为一个对象的方法。

SimpleXML旨在非常简单,因此它具有一小组函数,并且它专注于读取和写入数据。也就是说,您可以轻松读取或写入XML文件,可以更新某些值或删除某些节点(有一些限制!),仅此而已。没有花哨的操作,并且您无法访问不太常见的节点类型。例如,SimpleXML 无法创建 CDATA 节,尽管它可以读取它们。

DOM提供了DOM的完整实现以及一些非标准方法,例如appendXML。如果你习惯于在Javascript中操作DOM,你会在PHP的DOM中找到完全相同的方法。基本上,你可以做什么没有限制,它甚至可以处理HTML。这种丰富的功能的另一面是它比SimpleXML更复杂,更冗长。


附注

人们经常想知道/询问他们应该使用什么扩展来处理他们的XML或HTML内容。实际上,选择很容易,因为开始时没有太多的选择:

  • 如果你需要处理HTML,你真的别无选择:你必须使用DOM。
  • 如果你必须做任何花哨的事情,比如移动节点或附加一些原始XML,你几乎必须使用DOM。
  • 如果你需要做的就是读取和/或编写一些基本的XML(例如,与XML服务交换数据或读取RSS源),那么你可以使用其中任何一个。两者兼而有之
  • 如果你的XML文档太大,以至于它不适合内存,你不能使用任何一个,你必须使用XMLReader它也基于libxml2,使用起来更烦人,但仍然与其他人一起玩得很好

TL;DR

  • SimpleXML非常易于使用,但仅适用于90%的用例。
  • DOM 更复杂,但可以完成所有操作。
  • XMLReader 非常复杂,但使用的内存非常少。非常有情境。

推荐