PHPに2つのXMLパーサーが必要な理由を理解できません。
誰かがこれら2つの違いを説明できますか?
手短に:
SimpleXml
$root->foo->bar['attribute']
_[〜#〜] dom [〜#〜]
これらは両方とも libxml に基づいており、 libxml functions によってある程度影響を受ける可能性があります。
個人的に、SimpleXmlがあまり好きではありません。それは、ノードへの暗黙的なアクセスが好きではないからです。 _$foo->bar[1]->baz['attribute']
_。実際のXML構造をプログラミングインターフェイスに結び付けます。 Simple-XmlElementの動作はその内容に応じて魔法のように変化するため、one-node-type-for-everythingも少し直感的ではありません。
たとえば、_<foo bar="1"/>
_がある場合、_/foo/@bar
_のオブジェクトダンプは_/foo
_のオブジェクトダンプと同じになりますが、それらのエコーを実行すると異なる結果が出力されます。さらに、両方ともSimpleXml要素であるため、それらに対して同じメソッドを呼び出すことができますが、SimpleXmlElementがサポートしている場合にのみ適用されます。最初のSimpleXmlElementで$el->addAttribute('foo', 'bar')
を実行しようとしても何も実行されません。もちろん、属性ノードに属性を追加することはできませんが、ポイントは、属性ノードはそもそもそのメソッドを公開しないということです。
しかし、それは私の2cです。自分で決めてください:)
sidenoteには、2つのパーサーはありませんが、 PHPでさらにいくつか です。 SimpleXmlとDOMは、ドキュメントをツリー構造に解析する2つだけです。その他は、プルベースまたはイベントベースのパーサー/リーダー/ライターです。
私の答えもご覧ください
初心者が簡単に解答できるように、最短の回答を可能にします。また、簡潔にするために物事を少し単純化しています。誇張されたTL; DRバージョンについては、その答えの最後にジャンプしてください。
DOMとSimpleXMLは、実際には2つの異なるパーサーではありません。実際のパーサーは libxml2 で、DOMとSimpleXMLによって内部的に使用されます。したがって、DOM/SimpleXMLは同じパーサーを使用する2つの方法にすぎず、 1つのオブジェクト を another に変換する方法を提供します。
SimpleXMLは非常にシンプルにすることを目的としているため、小さな関数セットがあり、読み取りとデータの書き込み。つまり、XMLファイルを簡単に読み書きでき、 一部の値を更新する または一部のノードを削除することができます( 制限付き! )、それで終わりです。 手の込んだ操作はありません。あまり一般的ではないノードタイプにはアクセスできません。たとえば、SimpleXMLはCDATAセクションを作成できませんが、それらを読み取ることはできます。
[〜#〜] dom [〜#〜]は、 の本格的な実装を提供します [〜#〜] dom [〜#〜]+ appendXML などのいくつかの非標準メソッド。 JavascriptでDOMを操作することに慣れている場合、PHPのDOMでもまったく同じメソッドが見つかります。基本的に制限はありません、HTMLを処理します。この豊富な機能の裏返しは、SimpleXMLよりもより複雑で、より冗長であることです。
多くの場合、人々は自分のXMLまたはHTMLコンテンツを処理するためにどの拡張機能を使用する必要があるのか疑問に思います。実際には、最初に選択する選択肢があまりないため、選択は簡単です。
他の人が指摘したように、DOMおよびSimpleXML拡張機能は厳密には「XMLパーサー」ではなく、基盤となるlibxml2パーサーによって生成される構造への異なるインターフェイスです。
SimpleXMLインターフェースは、デコードされたJSON文字列を扱うのと同じ方法で、XMLをシリアル化されたデータ構造として扱います。そのため、ドキュメントのcontentsへの迅速なアクセスを提供し、名前による要素へのアクセス、および属性とテキストコンテンツの読み取り(自動折りたたみを含む)エンティティとCDATAセクション)。複数の名前空間を含むドキュメントをサポートし(主にchildren()
およびattributes()
メソッドを使用)、XPath式を使用してドキュメントを検索できます。また、コンテンツのbasic操作のサポートも含まれています。新しい文字列で要素または属性を追加または上書きします。
一方、DOMインターフェースは、XMLを構造化されたdocumentとして扱います。使用される表現は、表現されるデータと同じくらい重要です。したがって、エンティティやCDATAセクションなどのさまざまなタイプの「ノード」、およびコメントや処理命令などのSimpleXMLによって無視されるものに、よりきめ細かく明示的なアクセスを提供します。また、非常に豊富な操作機能セットが提供され、ノードの再配置や、テキストコンテンツの表現方法の選択などが可能になります。トレードオフはかなり複雑なAPIであり、多数のクラスとメソッドがあります。標準のAPI(元々JavaScriptでHTMLを操作するために開発された)を実装しているため、「自然なPHP」の感覚はあまりありませんが、一部のプログラマーは他のコンテキストから慣れている場合があります。
どちらのインターフェイスも、ドキュメント全体をメモリに解析する必要があり、その解析された表現にポインタを効果的にラップします。 simplexml_import_dom()
とdom_import_simplexml()
で2つのラッパーを切り替えることもできます。たとえば、DOM APIの関数を使用してSimpleXMLに「欠落」機能を追加できます。大きなドキュメントの場合は、「プルベース」 XMLReader または「イベントベース」 XMLパーサー の方が適切な場合があります。
SimpleXMLは、名前のとおり、XMLコンテンツの単純なパーサーであり、それ以外の何物でもありません。解析することはできません。たとえば、標準のHTMLコンテンツです。簡単で迅速なため、シンプルなアプリケーションを作成するための優れたツールです。
一方、DOM拡張ははるかに強力です。これにより、html、xhtml、xmlなど、ほぼすべてのDOMドキュメントを解析できます。これにより、出力コードを開いたり、書いたり、修正したりすることができ、xpathと全体的な操作がサポートされます。そのため、ライブラリは非常に複雑であるため、その使用法ははるかに複雑になり、大量のデータ操作が必要な大規模プロジェクトに最適なツールになります。
それがあなたの質問に答えることを願っています:)
2つのライブラリの最大の違いは、SimpleXMLが主に単一クラスSimpleXMLElement
であることです。対照的に、DOM拡張には多くのクラスがあり、それらのほとんどはDOMNode
のサブタイプです。
したがって、これらの2つのライブラリを比較する際の中心的な質問の1つは、DOMが提供する多くのクラスのうち、最後にSimpleXMLElement
で表すことができるクラスですか
以下は、XMLを扱う限り実際に役立つDOMNode
タイプ(有用なノードタイプ)を含む比較表です。マイレージは異なる場合があります。たとえば、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ノードを展開できます。 _LIBXML_NOCDATA
_オプション が _simplexml_load_*
_関数 または constructor とともに使用される場合、SimpleXMLはこれらを拡張します。 (オプションは DOMDocument::loadXML()
と同様に機能します)この表が示すように、SimpleXMLのインターフェースはDOMと比較して非常に限られています。テーブルの横にあるSimpleXMLElement
は、子と属性リストへのアクセスを抽象化し、要素名(プロパティアクセス)、属性(配列アクセス)、および Traversable
「独自の」子(要素または属性)を繰り返し、children()
およびattributes()
メソッドを介して名前空間アクセスを提供します。
このすべてのマジックインターフェースは問題ありませんが、SimpleXMLElementから拡張することによって変更することはできません。
SimpleXMLElementオブジェクトが表すノードタイプを確認するには、以下を参照してください。
DOMはここでDOMDocument Core Level 1仕様に従います 。そのインターフェイスを使用して、考えられるほぼすべてのXML処理を実行できます。ただし、レベル1のみであるため、3のような最新のDOMDocumentレベルと比較すると、一部のクールなものでは多少制限されています。確かにSimpleXMLもここで失われました。
SimpleXMLElementを使用すると、サブタイプにキャストできます。これはPHPでは非常に特殊です。 DOMではこれも許可されますが、少し手間がかかり、より具体的なノードタイプを選択する必要があります。
XPath 1. は両方でサポートされており、SimpleXMLの結果はarray
のSimpleXMLElements
であり、DOMではDOMNodelist
です。
SimpleXMLElement
は、文字列と配列(json)へのキャストをサポートしていますが、DOMのDOMNodeクラスはサポートしていません。それらは配列へのキャストを提供しますが、他のオブジェクトと同じようにのみ(キー/値としてのパブリックプロパティ)。
SimpleXMLElement
sをDOMにインポートでき、その逆も可能であることがわかります。 DOMの詳細と、拡張機能を使用してSimpleXMLElement
で実行できなかった(または方法を見つけられなかった)ことを行う方法について学習します。両方の拡張機能をお楽しみいただけます。両方を知っておくべきだと思います。より良い。 PHPのlibxmlベースの拡張機能はすべて非常に優れた強力な拡張機能です。そして、 php タグの下のStackoverflowでは、これらのライブラリを適切にカバーし、詳細な情報。