Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

मैं एक mysql डेटाटेबल में 600MB xml फ़ाइल के साथ 50MB ज़िप फ़ाइल कैसे प्राप्त करूं?

MySQL आपकी XML संरचना को नहीं जानता है। हालांकि यह सरल, अच्छी तरह से तैयार एक्सएमएल संरचनाओं को सीधे आयात कर सकता है, आपको अधिक जटिल संरचनाओं को स्वयं परिवर्तित करने की आवश्यकता होगी। आप CSV, SQL या एक (समर्थित) XML जेनरेट कर सकते हैं।

उस तरह की बड़ी फ़ाइलों के लिए XMLReader सबसे अच्छा API है। पहले एक इंस्टेंस बनाएं और फ़ाइल खोलें:

$reader = new XMLReader();
$reader->open('php://stdin');

आप नेमस्पेस का उपयोग कर रहे हैं, इसलिए मैं उनके लिए मैपिंग ऐरे को परिभाषित करने का सुझाव देता हूं:

$xmlns = [
  'a' => 'http://www.abc-example.com'
];

XML फ़ाइल के समान उपसर्ग/उपनाम का उपयोग करना संभव है, लेकिन आप स्वयं का भी उपयोग कर सकते हैं।

जब तक आपको पहला रिकॉर्ड तत्व नोड नहीं मिल जाता, तब तक एक्सएमएल नोड्स को पार करें:

while (
  $reader->read() && 
  ($reader->localName !== 'ABCRecord' ||  $reader->namespaceURI !== $xmlns['a'])
) {
  continue;
}

आपको स्थानीय नाम (नामस्थान उपसर्ग के बिना टैग नाम) और नामस्थान यूआरआई की तुलना करने की आवश्यकता है। इस तरह आपका प्रोग्राम XML फ़ाइल में वास्तविक उपसर्गों पर निर्भर नहीं करता है।

पहला नोड मिलने के बाद, आप उसी स्थानीय नाम से अगले भाई-बहन के पास जा सकते हैं।

while ($reader->localName === 'ABCRecord') {
  if ($reader->namespaceURI === 'http://www.abc-example.com') {
    // read data for the record ...
  }      
  // move to the next record sibling
  $reader->next('ABCRecord');
}

आप रिकॉर्ड डेटा को पढ़ने के लिए XMLReader का उपयोग कर सकते हैं लेकिन DOM और XPath अभिव्यक्तियों के साथ यह आसान है। XMLReader वर्तमान नोड को DOM नोड में विस्तारित कर सकता है। तो एक डोम दस्तावेज़ तैयार करें, इसके लिए एक XPath ऑब्जेक्ट बनाएं और नामस्थान पंजीकृत करें। नोड का विस्तार करने से नोड और सभी वंशज मेमोरी में लोड हो जाएंगे, लेकिन पैरेंट नोड या भाई-बहन नहीं।

$dom   = new DOMDocument;
$xpath = new DOMXpath($dom);
foreach ($xmlns as $prefix => $namespaceURI) {
  $xpath->registerNamespace($prefix, $namespaceURI);
}

while ($reader->localName === 'ABCRecord') {
  if ($reader->namespaceURI === 'http://www.abc-example.com') {
    $node = $reader->expand($dom);
    var_dump(
      $xpath->evaluate('string(a:ABC)', $node),
      $xpath->evaluate('string(a:Entity/a:LegalName)', $node)
    );
  }
  $reader->next('ABCRecord');
}

DOMXPath::evaluate() आपको DOM से अदिश मान या नोड सूचियाँ लाने के लिए Xpath व्यंजक का उपयोग करने की अनुमति देता है।

fputcsv() क्या सीएसवी में डेटा लिखना वाकई आसान हो जाएगा।

एक साथ रखें:

// open input
$reader = new XMLReader();
$reader->open('php://stdin');

// open output
$output = fopen('php://stdout', 'w');
fputcsv($output, ['id', 'name']);

$xmlns = [
  'a' => 'http://www.abc-example.com'
];

// prepare DOM
$dom   = new DOMDocument;
$xpath = new DOMXpath($dom);
foreach ($xmlns as $prefix => $namespaceURI) {
  $xpath->registerNamespace($prefix, $namespaceURI);
}

// look for the first record element
while (
  $reader->read() && 
  (
    $reader->localName !== 'ABCRecord' || 
    $reader->namespaceURI !== $xmlns['a']
  )
) {
  continue;
}

// while you have an record element
while ($reader->localName === 'ABCRecord') {
  if ($reader->namespaceURI === 'http://www.abc-example.com') {
    // expand record element node
    $node = $reader->expand($dom);
    // fetch data and write it to output
    fputcsv(
      $output, 
      [
        $xpath->evaluate('string(a:ABC)', $node),
        $xpath->evaluate('string(a:Entity/a:LegalName)', $node)
      ]
    );
  }

  // move to the next record sibling
  $reader->next('ABCRecord');
} 

आउटपुट:

id,name
5967007LIEEXZX4LPK21,"REGISTERENHETEN I Bornheim"
5967007LIE45ZX4MHC90,"SUNNDAL HOSTBANK"



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. सभी पंक्तियां हटाएं और नवीनतम x बाएं रखें

  2. MySQL - औसत पंक्ति लंबाई पूछताछ

  3. MySQL तालिका -> क्या आप एक ही पंक्ति को एक ही क्वेरी में कई बार वापस कर सकते हैं?

  4. दो टेबल से जॉइन हटाएं

  5. isset($_POST['submit']) अभी काम नहीं कर रहा है