Сравнить объект SimpleXml

Я пытаюсь сравнить два SimpleXML Objects .

Один из них извлекается из БД, а другой – из XML API, но результат всегда является ложным, независимо от того, действительно ли XML идентичен или нет.

Что я делаю не так?

 $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 aM 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 aM 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" } } 

Проблема здесь, так часто с SimpleXML, заключается в том, что SimpleXMLElement не является «нормальным» объектом PHP. SimpleXML не является парсером, который выплескивает полностью сформированные объекты PHP со свойствами и методами, но «живой» API, связанный с внутренним представлением XML-документа.

На странице руководства « Сравнение объектов» указано, что «Два экземпляра объекта равны, если они имеют одинаковые атрибуты и значения и являются экземплярами одного и того же класса». Когда вы запускаете print_r() или var_dump() поверх SimpleXMLElement, у него есть свойства, представляющие дочерние узлы и атрибуты, которые будут одинаковыми для двух объектов, построенных из идентичного XML. Однако фактическая реализация содержит только указатель на структуру памяти, созданную при анализе XML, которая будет отличаться, даже если вы будете разбирать одну и ту же строку дважды. Таким образом, простое сравнение двух объектов SimpleXMLElement с символом == никогда не вернет true .

Фактическое решение зависит от того, что именно вы хотите сравнить:

  • если вы хотите, чтобы конкретный фрагмент XML был на 100% идентичен между двумя документами, вы можете использовать ->asXML() чтобы получить строку XML для этой части документа; например $objDbXml->Reise->Z_LEISTUNGEN->asXML() == $objApiXml->Reise->Z_LEISTUNGEN->asXML()
  • если есть несколько конкретных свойств, которые вы хотите сравнить, вам может быть лучше выбрать их и сравнить их по отдельности, чтобы тест возвращался к истине, даже если они отображаются в несколько другом порядке или со специальными символами, закодированными несколько иначе

Библиотека с открытым исходным кодом TurboCommons содержит класс XMLUtils, который содержит мощный метод сравнения xml, называемый isEqualTo ().

С его помощью вы можете проверить, равны или нет две строки xml или simplexml, даже если их элементы и атрибуты имеют другой порядок.

https://github.com/edertone/TurboCommons

Чтобы использовать его, загрузите файл phar и импортируйте его в свой проект.

Простой пример того, как он работает:

 use org\turbocommons\src\main\php\utils\XmlUtils; XmlUtils::isEqualTo('<root><a/></root>', '<root><a></a></root>'); // Returns true XmlUtils::isEqualTo('<root><a/></root>', '<raat><a/></raat>'); // Returns false