2009-07-22 14 views
26

मुझे PHP में बड़ी एक्सएमएल फाइलों को पार्स करना है, उनमें से एक 6.5 एमबी है और वे भी बड़ा हो सकते हैं। जैसा कि मैंने पढ़ा है SimpleXML एक्सटेंशन, पूरी फ़ाइल को किसी ऑब्जेक्ट में लोड करता है, जो बहुत कुशल नहीं हो सकता है। आपके अनुभव में, सबसे अच्छा तरीका क्या होगा?PHP में बड़े एक्सएमएल को संसाधित करने का सबसे अच्छा तरीका

+0

चेक बाहर [खींचो PHP में पार्सिंग] (http://www.ibm.com/ developerworks/xml/library/x-pullparsingphp/index.html) – Randolpho

+0

आलेख XMLReader के बारे में है: http://php.net/manual/en/book.xmlreader.php "SimpleXML के विपरीत, यह एक पूर्ण XML पार्सर है जो हैंडल करता है सभी दस्तावेज, उनमें से कुछ नहीं। डोम के विपरीत, यह उपलब्ध स्मृति से बड़े दस्तावेज़ों को संभाल सकता है। एसएएक्स के विपरीत, यह आपके प्रोग्राम को नियंत्रण में रखता है। " – WayFarer

+0

मैंने लोगों को XMLReader के साथ अच्छी सफलता प्राप्त की है: http://php.net/manual/en/book.xmlreader.php – Steven

उत्तर

21

एक बड़ी फ़ाइल के लिए, आप एक DOM पार्सर के बजाय SAX parser का उपयोग करना चाहेंगे।

एक डोम पार्सर के साथ यह पूरी फ़ाइल में पढ़ेगा और इसे स्मृति में ऑब्जेक्ट पेड़ में लोड करेगा। एक SAX पार्सर के साथ, यह अनुक्रमिक रूप से फ़ाइल को पढ़ेगा और डेटा को नियंत्रित करने के लिए आपके उपयोगकर्ता द्वारा परिभाषित कॉलबैक फ़ंक्शंस को कॉल करेगा (टैग टैग, एंड टैग, सीडीएटीए इत्यादि)

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

3

यह वास्तव में इस बात पर निर्भर करता है कि आप डेटा के साथ क्या करना चाहते हैं? क्या आपको इसे प्रभावी ढंग से काम करने के लिए स्मृति में सभी की आवश्यकता है?

6.5 एमबी आज के कंप्यूटर के मामले में इतना बड़ा नहीं है। उदाहरण के लिए, उदाहरण के लिए, ini_set('memory_limit', '128M');

हालांकि, यदि आपका डेटा स्ट्रीम किया जा सकता है, तो आप SAX parser का उपयोग करना चाह सकते हैं। यह वास्तव में आपकी उपयोग आवश्यकताओं पर निर्भर करता है।

+3

हालांकि फ़ाइल पार्सिंग के बाद 6.5MB है, यह बहुत बड़ा है। मेरे पास यह 20 एमबी एक्सएमएल था, जब 'xml_parse_into_struct' को कॉल करते समय, मुझे स्मृति_limit को 512 एमबी पर सेट करने की आवश्यकता है, अन्यथा यह असफल हो जाएगा। – faulty

6

एरिक पेट्रोलेजे की सिफारिश के अनुसार एक एसएक्स पार्सर, बड़ी एक्सएमएल फाइलों के लिए बेहतर होगा। एक डीओएम पार्सर पूरी एक्सएमएल फ़ाइल में लोड करता है और आपको एक्सपैथ प्रश्नों को चलाने की इजाजत देता है - एक एसएएक्स (एक्सएमएल के लिए सरल एपीआई) पार्सर एक समय में केवल एक पंक्ति पढ़ेगा और आपको प्रसंस्करण के लिए हुक पॉइंट देगा।

+0

उदाहरण लिंक छोड़ने के लिए धन्यवाद :) –

+0

ऑब्जेक्ट ओरिएंटेड उदाहरण: http://php-and-symfony.matthiasnoback.nl/2012/04/php-create-an-object-oriented-xml-parser-using-the- अंतर्निर्मित xml_-functions/ –

1

SAX पार्सर जाने का रास्ता है। मैंने पाया है कि यदि आप संगठित नहीं रहते हैं तो SAX पार्सिंग गन्दा हो सकती है।

मैं बड़ी एक्सएमएल फाइलों को पार्स करने के लिए एसटीएक्स (एक्सएमएल के लिए स्ट्रीमिंग ट्रांसफॉर्मेशन) के आधार पर एक दृष्टिकोण का उपयोग करता हूं। मैं वर्तमान संदर्भ में डेटा का ट्रैक रखने के लिए एक सरलXML ऑब्जेक्ट बनाने के लिए SAX विधियों का उपयोग करता हूं (यानी रूट और वर्तमान नोड के बीच नोड्स)। अन्य कार्यों का उपयोग तब SimpleXML दस्तावेज़ को संसाधित करने के लिए किया जाता है।

1

मुझे एक बड़ी एक्सएमएल फ़ाइल को पार्स करने की आवश्यकता है जो प्रत्येक पंक्ति (स्टैक ओवरफ्लो डेटा डंप) पर एक तत्व है। इस विशिष्ट मामले में फ़ाइल को एक समय में एक पंक्ति को पढ़ने के लिए पर्याप्त था और SimpleXML का उपयोग करके प्रत्येक पंक्ति को पार्स करना था। मेरे लिए यह कुछ नया सीखने का लाभ नहीं था।

11

उस पर लेने के लिए मेरे:

https://github.com/prewk/XmlStreamer

एक साधारण वर्ग है कि जब फ़ाइल स्ट्रीमिंग XML मूल तत्व को सभी बच्चों को निकाल देंगे। ने pubmed.com से 108 एमबी एक्सएमएल फ़ाइल पर परीक्षण किया।

class SimpleXmlStreamer extends XmlStreamer { 
    public function processNode($xmlString, $elementName, $nodeIndex) { 
     $xml = simplexml_load_string($xmlString); 

     // Do something with your SimpleXML object 

     return true; 
    } 
} 

$streamer = new SimpleXmlStreamer("myLargeXmlFile.xml"); 
$streamer->parse(); 
+0

ओस्कार्थ: मुझे इस वर्ग का उपयोग करने का तरीका नहीं मिल रहा है, क्या आप मुझे थोड़ा सा ज्ञान देते हैं? या आप पूर्ण कोड पोस्ट कर सकते हैं? –

+4

वाह! 10 मिनट में मुझे 4 जीबी एक्सएमएल फाइल के लिए काम मिल गया। मिलनसार। – Slawa

+0

मैं पहले 'XMLReader' का उपयोग कर रहा था, लेकिन अगर दस्तावेज़ अच्छी तरह से गठित नहीं होता है तो यह दुर्घटनाग्रस्त हो जाता है। यह वर्ग समस्या हल करती है और बहुत तेज है। – Drahcir

7

बड़े एक्सएमएल फाइल के साथ एक DOMDocument का उपयोग कर, मत भूलना load() विधि के विकल्पों में LIBXML_PARSEHUGE ध्वज पारित करने के लिए।(एक ही DOMDocument वस्तु के अन्य load तरीकों के लिए लागू होता है)

$checkDom = new \DOMDocument('1.0', 'UTF-8'); 
    $checkDom->load($filePath, LIBXML_PARSEHUGE); 

(एक 120mo एक्सएमएल फ़ाइल के साथ काम करता है)