6

私は2つを比較しようとしていSimpleXML Objectsます。

1 つは DB からフェッチされ、もう 1 つは XML API からフェッチされますが、XML が実際に同一であるかどうかにかかわらず、結果は常に false です。

私は何を間違っていますか?

$objDbXml   = simplexml_load_string($objReisen->xml); // XML from DB           
$objApiXml  = simplexml_load_string(getXMlFromApi()); // XML from Api
var_dump($objDbXml->Reise->Z_LEISTUNGEN == $objApiXml->Reise->Z_LEISTUNGEN);
// Result is always false

var_dump($objDbXml->Reise->Z_LEISTUNGEN , $objApiXml->Reise->Z_LEISTUNGEN) の出力:

object(SimpleXMLElement) #69 (1) {
    ["TextLine"]= > array(11) {
        [0] = > string(43) "Erlebnisreise mit höchstens 13 Teilnehmern" 
        [1] = > string(39) "Durchführungsgarantie ab 4 Teilnehmern" 
        [2] = > string(127) "Linienflug mit South African Airways von Frankfurt a.M. nach Kapstadt und zurück von Port Elizabeth (von München auf Anfrage)" 
        [3] = > string(28) "Reiseminibus mit Klimaanlage" 
        [4] = > string(111) "Übernachtungen in Hotels und Lodges sowie 2 Übernachtungen in einer exklusiven Lodge im Kariega Game Reserve" 
        [5] = > string(67) "Täglich Frühstück, 2 x Mittagessen, 4 x Abendessen, 1 Weinprobe" 
        [6] = > string(123) "1 Safari im Addo-Elephant-NP; 2 Safaris im offenen Geländewagen, 1 Wandersafari und 1 Bootsfahrt im Kariega Game Reserve" 
        [7] = > string(41) "Nationalparkgebühren und Eintrittsgelder"
        [8] = > string(14) "Reiseliteratur" 
        [9] = > string(43) "Zertifikat über 100 m² Regenwald für Sie" 
        [10] = > string(42) "Deutsch sprechende Chamäleon-Reiseleitung"
    }
}

object(SimpleXMLElement) #67 (1) {
    ["TextLine"]= > array(11)
    {
        [0] = > string(43) "Erlebnisreise mit höchstens 12 Teilnehmern" 
        [1] = > string(39) "Durchführungsgarantie ab 4 Teilnehmern" 
        [2] = > string(127) "Linienflug mit South African Airways von Frankfurt a.M. nach Kapstadt und zurück von Port Elizabeth (von München auf Anfrage)" 
        [3] = > string(28) "Reiseminibus mit Klimaanlage" 
        [4] = > string(111) "Übernachtungen in Hotels und Lodges sowie 2 Übernachtungen in einer exklusiven Lodge im Kariega Game Reserve" 
        [5] = > string(67) "Täglich Frühstück, 2 x Mittagessen, 4 x Abendessen, 1 Weinprobe" 
        [6] = > string(123) "1 Safari im Addo-Elephant-NP; 2 Safaris im offenen Geländewagen, 1 Wandersafari und 1 Bootsfahrt im Kariega Game Reserve" 
        [7] = > string(41) "Nationalparkgebühren und Eintrittsgelder" 
        [8] = > string(14) "Reiseliteratur" 
        [9] = > string(43) "Zertifikat über 100 m² Regenwald für Sie" 
        [10] = > string(42) "Deutsch sprechende Chamäleon-Reiseleitung"
    }
}
4

2 に答える 2

12

ここでの問題は、SimpleXML でよくあることですが、SimpleXMLElement が「通常の」PHP オブジェクトではないという事実にあります。SimpleXML は、プロパティとメソッドを備えた完全な形式の PHP オブジェクトを吐き出すパーサーではなく、XML ドキュメントの内部表現にリンクされた「ライブ」API です。

Comparing Objectsのマニュアル ページには、「2 つのオブジェクト インスタンスは、それらが同じ属性と値を持ち、同じクラスのインスタンスである場合、等しい」と記載されています。SimpleXMLElementを実行print_r()すると、子ノードと属性を表すプロパティが表示されます。これは、同一の XML から構築された 2 つのオブジェクトで同じになります。ただし、実際の実装には、XML が解析されたときに作成されたメモリ構造へのポインターのみが含まれています。これは、同じ文字列を 2 回解析した場合でも異なります。したがって、単純に 2 つの SimpleXMLElement オブジェクトを比較しても、は返されません。var_dump()==true

実際の解決策は、正確に比較したいものによって異なります。

  • XML の特定のフラグメントが 2 つのドキュメント間で 100% 同一であるかどうかを確認したい場合は->asXML()、ドキュメントのその部分の XML 文字列を取得するために使用できます。例えば$objDbXml->Reise->Z_LEISTUNGEN->asXML() == $objApiXml->Reise->Z_LEISTUNGEN->asXML()
  • 比較したい特定のプロパティがいくつかある場合は、それらを選択して個別に比較する方がよい場合があります。これにより、それらがわずかに異なる順序で表示されたり、特殊文字がわずかに異なってエンコードされたりしても、テストは true を返します。
于 2013-07-30T17:45:57.067 に答える