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

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

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

简而言之:

SimpleXML的

  • 是简单的XML和/或简单的UseCases
  • 有限的API来处理节点(例如,不能编程到一个接口,太多)
  • 所有节点都是同一types的(元素节点与属性节点相同)
  • 节点是神奇的访问,例如$root->foo->bar['attribute']

DOM

  • 是任何XML UseCase你可能有
  • 是W3C DOM API的实现(在许多语言中实现)
  • 区分各种节点types(更多控制)
  • 由于显式的API(可以编码到一个接口)
  • 可以parsing破碎的HTML
  • 允许您在XPath查询中使用PHP函数

这两个都是基于libxml的 ,可以通过libxml函数进行一些扩展


就个人而言 ,我不喜欢SimpleXml太多。 这是因为我不喜欢对节点的隐式访问,例如$foo->bar[1]->baz['attribute'] 。 它将实际的XML结构绑定到编程接口。 单节点types的东西也有点不直观,因为SimpleXmlElement的行为会根据其内容而奇迹般地改变。

例如,当你有<foo bar="1"/> /foo/@bar的对象转储将与/foo/@bar的对象转储相同,但是对它们进行回显将会打印出不同的结果。 而且,因为它们都是SimpleXml元素,所以你可以在它们上调用相同的方法,但是只有在SimpleXmlElement支持时才会被应用,比如试图在$el->addAttribute('foo', 'bar')上第一个SimpleXmlElement什么也不做。 现在当然是不能将属性添加到属性节点的,但重点是,属性节点不会首先公开该方法。

但那只是我的2c。 做你自己的想法 🙂


旁注中 ,没有两个parsing器,但在PHP中有更多 。 SimpleXml和DOM只是将文档parsing为树结构的两个部分。 其他人是拉或基于事件的parsing器/读者/作家。

另请参阅我的答案

  • 最适合PHP的XMLparsing器

我将尽可能地做出最短的回答,以便初学者可以轻松将其拿走。 为了简短起见,我也稍微简化了一些事情。 跳到这个答案的末尾,夸大TL,DR版本。


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

SimpleXML意图是非常简单的,所以它有一小部分function,它专注于读取和写入数据 。 也就是说,您可以轻松读取或写入XML文件,您可以更新一些值或删除一些节点( 有一些限制! ),就是这样。 没有花哨的操作 ,你不能访问不太常见的节点types。 例如,SimpleXML不能创buildCDATA节,尽pipe它可以读取它们。

DOM提供了一个完整的DOM实现,还有一些非标准的方法,比如appendXML 。 如果您习惯在Javascript中操作DOM,您将在PHP的DOM中find完全相同的方法。 你可以做什么基本上没有限制 ,它平衡处理HTML。 function丰富的反面是它比SimpleXML 更复杂更冗长。


边注

人们经常想知道/问他们应该使用什么扩展来处理他们的XML或HTML内容。 其实这个select很容易,因为没有太多select可供select:

  • 如果你需要处理HTML,你没有select:你必须使用DOM
  • 如果你不得不做任何事情,比如移动节点或者添加一些原始的XML,那么你几乎不得不使用DOM
  • 如果您只需要读取和/或写入一些基本的XML(例如与XML服务交换数据或阅读RSS提要),那么您可以使用其中一种。 或 两者 。
  • 如果你的XML文档太大以至于不能适应内存,那么你就不能使用XML文档,而且你必须使用也是基于libxml2的XMLReader ,使用起来更麻烦,但是仍然可以和其他人一起使用

TL; DR

  • SimpleXML非常容易使用,但只对90%的用例有用。
  • DOM更复杂,但是可以做所有事情。
  • XMLReader是非常复杂的,但使用很less的内存。 非常情景化。

正如其他人所指出的那样,DOM和SimpleXML扩展不是严格意义上的“XMLparsing器”,而是它们与底层libxml2parsing器生成的结构的不同接口。

SimpleXML接口将XML视为序列化的数据结构,与处理解码的JSONstring的方式相同。 因此,它提供了对文档内容的快速访问,重点是按名称访问元素,并读取其属性和文本内容(包括自动折叠实体和CDATA部分)。 它支持包含多个名称空间的文档(主要使用children()attributes()方法),并且可以使用XPathexpression式search文档。 它还包括对内容的基本操作的支持 – 例如用新string添加或覆盖元素或属性。

另一方面,DOM接口将XML视为结构化文档 ,其中使用的表示与所表示的数据同样重要。 因此,它提供了对不同types的“节点”(比如实体和CDATA节)以及SimpleXML忽略的一些内容(例如注释和处理指令)的更详细和明确的访问。 它还提供了一组更丰富的操作函数,例如,允许您重新排列节点并select如何表示文本内容。 权衡是一个相当复杂的API,有大量的类和方法; 因为它实现了一个标准的API(最初是为了在JavaScript中操作HTML而开发的),可能会有一些“自然的PHP”的感觉,但是一些程序员可能从其他上下文中熟悉它。

这两个接口都需要将完整的文档parsing到内存中,并有效地将指针包装到parsing的表示中; 您甚至可以使用simplexml_import_dom()dom_import_simplexml()在两个包装之间切换,例如使用DOM API中的函数向SimpleXML添加“缺less”特征。 对于较大的文档,“基于拉”的XMLReader或“基于事件的” XMLparsing器可能更合适。

作为名称状态,SimpleXML是XML内容的简单parsing器,除此之外别无其他。 你不能parsing,让我们说标准的HTML内容。 它简单快捷,因此是创build简单应用程序的绝佳工具。

另一方面,DOM扩展function更强大。 它使您能够parsing几乎所有的DOM文档,包括html,xhtml,xml。 它使您能够打开,写入甚至更正输出代码,支持xpath和更多的操作。 因此,它的使用要复杂得多,因为图书馆是相当复杂的,这使得它成为需要大量数据操作的大型项目的理想工具。

希望这能回答你的问题 :)

SimpleXMLElement可以表示哪些DOMNode?

这两个库最大的区别在于,SimpleXML主要是一个类: SimpleXMLElement 。 相比之下,DOM扩展有许多类,其中大多数是DOMNode一个子types。

所以比较这两个库的核心问题是DOM提供的许多类中的哪一个可以用SimpleXMLElement来表示呢?

以下是包含那些实际上有用的DOMNodetypes的比较表,只要涉及处理XML(有用的节点types)。 您的里程可能会有所不同,例如,当您需要处理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将文本节点抽象为元素的string值(比较__toString )。 只有当元素仅包含文本时,这才起作用,否则文本信息可能会丢失。
  • [2] :每个XMLparsing器都可以在加载文档时扩展CDATA节点。 当LIBXML_NOCDATA选项与simplexml_load_*函数或构造 函数一起使用时,SimpleXML LIBXML_NOCDATA这些进行扩展。 (选项也适用于DOMDocument::loadXML()

如下表所示,与DOM相比,SimpleXML的界面非常有限。 在表格中的SimpleXMLElementSimpleXMLElement还抽象访问子对象和属性列表,以及通过元素名称(属性访问),属性(数组访问)以及作为Traversable迭代它的“自己”子元素(元素或属性),并通过children()attributes()方法提供名称空间访问。

只要所有这个神奇的界面都很好,但是它不能通过从SimpleXMLElement扩展来改变,就像魔术一样,因为它也是有限的。

要找出SimpleXMLElement对象所代表的节点types,请参阅:

  • 如何区分代表元素和属性的SimpleXML对象?

DOM在这里遵循DOMDocument核心级别1规范 。 你几乎可以用这个接口完成所有可以想象的XML处理。 然而,它只是一级,所以与现代的DOMDocument Levels比较,比起3级,对于一些较冷的东西来说,这是有限的。 当然SimpleXML也在这里输了。

SimpleXMLElement允许转换为子types。 这在PHP中是非常特殊的。 DOM也允许这样做,尽pipe它有一点点的工作,需要select更具体的节点types。

XPath 1.0由两者支持,SimpleXML中的结果是一个SimpleXMLElements array ,在DOM中是一个DOMNodelist

SimpleXMLElement支持转换为string和数组(json),DOM中的DOMNode类不会。 他们提供铸造到数组,但只有像任何其他对象(公共属性作为键/值)。

PHP中这两个扩展的常见使用模式是:

  • 您通常开始使用SimpleXMLElement。 您对XML和XPath的知识水平处于同样的低水平。
  • 在与界面的魔力作战之后,迟早会达到一定程度的挫败感。
  • 您发现可以将SimpleXMLElement导入到DOM中,反之亦然。 您将学习更多关于DOM的知识,以及如何使用扩展来完成SimpleXMLElement无法实现的function(或无法了解如何操作)。
  • 您注意到您可以使用DOM扩展加载HTML文档。 和无效的XML。 并做输出格式。 事情SimpleXMLElement不能做。 甚至没有肮脏的伎俩。
  • 你甚至可能完全切换到DOM扩展,因为至less你知道接口是更多的区别,并允许你做的东西。 另外,您还可以在学习DOM级别1时看到一些好处,因为您可以在Javascript和其他语言中使用它(DOM扩展的许多优点)。

你可以玩两个扩展,我想你应该都知道。 越多越好。 PHP中所有基于libxml的扩展都是非常好的扩展。 而在PHP标签下的Stackoverflow有一个很好的传统涵盖这些图书馆,并与详细的信息。