2012-04-25 6 views
6

तो मान लें कि मैं दो DOMDocument ऑब्जेक्ट्स की तुलना करना चाहता हूं। उनके पास एक ही सामग्री है लेकिन ऑर्डर और स्वरूपण बंद हो सकता है।PHPUnit के साथ समान XML की तुलना कैसे करें?

<responses> 
    <response id="12"> 
     <foo>bar</foo> 


<lorem>ipsum</lorem> 
      <sit>dolor</sit> 

    </response></responses> 

अन्य एक आउटपुट:

<responses> 
<response id="12"> 

      <lorem>ipsum</lorem><sit>dolor</sit> 
     <foo>bar</foo> 
          </response> 
</responses> 

आप देख सकते हैं, वे एक ही XML संरचना को शामिल लेकिन कुछ घटक अलग आदेश और स्वरूपण में हो सकता है उदाहरण के लिए, पहले एक इस XML आउटपुट पूरी तरह से यादृच्छिक है।

अगर मैं कार्य करें: असफल

$this->assertEquals(); 

परीक्षण पाठ्यक्रम की इच्छा। मैं सिर्फ एक्सएमएल संरचना का परीक्षण नहीं करना चाहता बल्कि सामग्री भी चाहता हूं।

कोई विचार?

+0

सभी सफेद रिक्त स्थान को हटाने और फिर sha1 हैश की तुलना करने के बारे में कैसे? –

उत्तर

3
+1

जबकि यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, [यह बेहतर होगा] (http://meta.stackexchange.com/q/8259) यहां उत्तर के आवश्यक हिस्सों को शामिल करने के लिए, और संदर्भ के लिए लिंक प्रदान करें। – Nanne

+1

दरअसल, लिंक अब टूट गया है, इस जवाब को आज बेकार बना दिया गया है। – nIcO

+0

@nIcO टूटा हुआ लिंक –

3

PHPUnit का कौन सा संस्करण यह है? मुझे यकीन है कि हाल के संस्करण सभी डोम डॉक्यूमेंट तुलनाओं का समर्थन करते हैं।

लघु संस्करण: व्हाइटस्पेस को हटाने के लिए $doc->preserveWhiteSpace सेटिंग का उपयोग करें, और फिर टिप्पणियों को रोकने के लिए $doc->C14N() का उपयोग करें और एक स्ट्रिंग प्राप्त करें जिसका आप तुलना कर सकते हैं।


ठीक है, यहाँ एक स्क्रिप्ट आप के साथ खेल सकते है, ध्यान दें कि EOD; लाइनों किसी भी अनुगामी या अग्रणी खाली स्थान के नहीं हो सकता।

$x1 = <<<EOD 
<responses> 
    <response id="12"> 
     <foo>bar</foo> 

<lorem>ipsum</lorem> 
      <sit>dolor</sit> 
     <!--This is a comment --> 

    </response></responses> 
EOD; 

$x2 = <<<EOD 
<responses> 
<response id="12"> 

      <lorem>ipsum</lorem><sit>dolor</sit> 
     <foo>bar</foo> 
     <!--This is another comment --> 
          </response> 
</responses> 
EOD; 

// अगले ब्लॉक एक ही फाइल का हिस्सा है, मैं सिर्फ इतना है कि StackOverflow वाक्य रचना-प्रकाश डाला प्रणाली गला घोंटना नहीं है इस स्वरूपण ब्रेक बना रहा हूं।

$USE_C14N = true; // Try false, just to see the difference. 

$d1 = new DOMDocument(1.0); 
$d2 = new DOMDocument(1.0); 

$d1->preserveWhiteSpace = false; 
$d2->preserveWhiteSpace = false; 

$d1->formatOutput = false; // Only useful for "pretty" output with saveXML() 
$d2->formatOutput = false; // Only useful for "pretty" output with saveXML() 

$d1->loadXML($x1); // Must be done AFTER preserveWhiteSpace and formatOutput are set 
$d2->loadXML($x2); // Must be done AFTER preserveWhiteSpace and formatOutput are set 

if($USE_C14N){ 
    $s1 = $d1->C14N(true, false); 
    $s2 = $d2->C14N(true, false); 
} else { 
    $s1 = $d1->saveXML(); 
    $s2 = $d2->saveXML(); 
} 

echo $s1 . "\n"; 
echo $s2 . "\n"; 

साथ $USE_C14N=false;

<?xml version="1.0"?> 
<responses><response id="12"><foo>bar</foo><lorem>ipsum</lorem><sit>dolor</sit><!--This is a comment --></response></responses> 

<?xml version="1.0"?> 
<responses><response id="12"><lorem>ipsum</lorem><sit>dolor</sit><foo>bar</foo><!--This is another comment --></response></responses> 

नोट के साथ $USE_C14N=true;

<responses><response id="12"><foo>bar</foo><lorem>ipsum</lorem><sit>dolor</sit></response></responses> 
<responses><response id="12"><lorem>ipsum</lorem><sit>dolor</sit><foo>bar</foo></response></responses> 

आउटपुट आउटपुट कि $doc->C14N() धीमी हो सकती है, लेकिन मुझे लगता है कि यह संभावना है कि टिप्पणियों बाहर अलग करना वांछनीय है लगता है। ध्यान दें कि यह सब यह भी मानता है कि आपके एक्सएमएल में व्हाइटस्पेस महत्वपूर्ण नहीं है, और शायद कुछ उपयोग-मामले हैं जहां यह धारणा सही नहीं है ...

1

मेरा सुझाव है कि आप एक्सएमएल को DOMDocuments में बदल दें और फिर उपयोग करें उन लोगों के साथ assertEquals। यह पहले से ही PHPUnit द्वारा समर्थित है - हालांकि यह आपकी सभी आवश्यकताओं को पहले से कवर नहीं कर सकता है।

आप कर सकते हैं फिर से प्रारूप दस्तावेज और उन्हें साथ ही फिर से लोड करते हैं, PHP XML how to output nice format देखें:

$doc->preserveWhiteSpace = false; 
$doc->formatOutput = true; 

एक और विचार तो सॉर्ट करने के लिए उनके टैगनाम द्वारा बच्चों है - पता नहीं है कि अगर पहले किया गया है।

0

आप PHPUnit के assertXmlFileEqualsXmlFile(), assertXmlStringEqualsXmlFile() और assertXmlStringEqualsXmlString() फ़ंक्शन का उपयोग कर सकते हैं; अभी तक, वे क्या अलग है पर जानकारियां देना नहीं है, वे केवल परीक्षण

Failed asserting that two DOM documents are equal. 

के साथ विफल करते तो तुम PHP के XMLDiff PECL extension, या अपना खुद पुनरावर्ती तुलना समारोह लिखने के लिए चाहते हो सकता है। यदि समय मायने रखता है, तो मैं सरल API की वजह से डीओएम लेकिन SimpleXML का उपयोग न करने की अनुशंसा करता हूं।

0

मैं यहां प्रस्तुत कुछ विचारों के साथ खेल रहा हूं और अनुमान लगाया है कि मैं अपना अंतिम परिणाम भी पोस्ट कर सकता हूं। उन चीजों में से एक जो मैं करना चाहता था वह दो नोड्स या दो दस्तावेजों के परिणामों की तुलना करना था। (तकनीकी रूप से, यह एक या तो लंबे समय से तुलना कर सकता है क्योंकि इसी तरह के दस्तावेज़ के पहले बच्चे की तुलना दूसरे की तुलना में की जा रही है)

असल में यदि मैं डोम डॉक्यूमेंट में भेजता हूं, तो यह $ क्लोन-> loadXml ($ obj -> saveXml) लेकिन अगर यह एक नोड भेजा गया है, तो यह $ क्लोन-> importNode ($ obj) करता है; ifs का क्रम महत्वपूर्ण हो जाता है क्योंकि DomDocument भी DomNode का एक उदाहरण है।

/** 
* @param \DOMDocument|\DOMNode $n1 
* @param \DOMDocument|\DOMNode $n2 
* @return bool 
* @throws \Exception for invalid data 
*/ 
function compareNode($n1, $n2) 
{ 
    $nd1 = new \DOMDocument('1.0', "UTF-8"); 
    if ($n1 instanceof \DOMDocument) { 
     $nd1 = $n1->cloneNode(true); 
     $nd1->preserveWhiteSpace = false; 
     $nd1->formatOutput = false; 
     $nd1->loadXML($n1->saveXML()); 
    } elseif ($n1 instanceof \DOMNode) { 
     $nd1->preserveWhiteSpace = false; 
     $nd1->formatOutput = false; 
     $nd1->importNode($n1); 
    } else { 
     throw new \Exception(__METHOD__ . " node 1 is invalid"); 
    } 

    $nd2 = new \DOMDocument('1.0', "UTF-8"); 
    if ($n2 instanceof \DOMDocument) { 
     $nd2 = $n2->cloneNode(true); 
     $nd2->preserveWhiteSpace = false; 
     $nd2->formatOutput = false; 
     $nd2->loadXML($n2->saveXML()); 
    } elseif ($n1 instanceof \DOMNode) { 
     $nd2->preserveWhiteSpace = false; 
     $nd2->formatOutput = false; 
     $nd2->importNode($n2); 
    } else { 
     throw new \Exception(__METHOD__ . " node 2 is invalid"); 
    } 

    return ($nd1->C14N(true, false) == $nd2->C14N(true, false)); 
} 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^