6

我正在尝试比较两个SimpleXML Objects.

一个是从 DB 中获取的,另一个是从 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 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。

比较对象的手册页指出“如果两个对象实例具有相同的属性和值,并且是同一类的实例,则它们是相等的。” 当您运行print_r()var_dump()在 SimpleXMLElement 上运行时,它似乎具有表示子节点和属性的属性,这对于从相同 XML 构建的两个对象来说是相同的。但是,实际的实现只包含一个指向在解析 XML 时创建的内存结构的指针,即使您将相同的字符串解析两次,它也会有所不同。因此,简单地比较两个 SimpleXMLElement 对象==将永远不会返回true

实际的解决方案取决于您要比较的具体内容:

  • 如果您想查看 XML 的特定片段在两个文档之间是否 100% 相同,您可以使用->asXML()获取文档该部分的 XML 字符串;例如$objDbXml->Reise->Z_LEISTUNGEN->asXML() == $objApiXml->Reise->Z_LEISTUNGEN->asXML()
  • 如果您想要比较一些特定的属性,您最好选择它们并单独比较它们,这样即使它们以稍微不同的顺序出现,或者特殊字符的编码略有不同,测试也会返回 true
于 2013-07-30T17:45:57.067 回答
1

开源 TurboCommons 库包含一个名为 XMLUtils 的类,该类包含一个名为 isEqualTo() 的强大的 xml 比较方法。

使用它,您可以检查两个 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
于 2017-03-11T16:14:33.183 回答