sql >> Databáze >  >> RDS >> Mysql

Jak dostanu 50 MB zip soubor se 600 MB xml souborem do mysql datatable?

MySQL nezná vaši XML strukturu. I když může přímo importovat jednoduché, dobře tvarované struktury XML, složitější struktury budete muset převést sami. Můžete vygenerovat CSV, SQL nebo (podporovaný) XML.

Pro velké soubory, jako je tento, je XMLReader nejlepší API. Nejprve vytvořte instanci a otevřete soubor:

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

Používáte jmenné prostory, takže pro ně navrhuji definovat pole mapování:

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

Je možné použít stejné předpony/aliasy jako v souboru XML, ale můžete použít i své vlastní.

Dále procházejte uzly XML, dokud nenajdete první uzel prvku záznamu:

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

Musíte porovnat místní název (název značky bez předpony jmenného prostoru) a URI jmenného prostoru. Tímto způsobem vaše programování nezávisí na skutečných prefixech v souboru XML.

Poté, co najdete první uzel, můžete přejít k dalšímu sourozenci se stejným místním názvem.

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');
}

Ke čtení dat záznamu můžete použít XMLReader, ale s výrazy DOM a XPath je to jednodušší. XMLReader může rozšířit aktuální uzel na uzel DOM. Připravte si tedy dokument DOM, vytvořte pro něj objekt XPath a zaregistrujte jmenné prostory. Rozbalení uzlu načte uzel a všechny potomky do paměti, ale ne nadřazené uzly nebo sourozence.

$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() umožňuje použít výraz Xpath k načtení skalárních hodnot nebo seznamů uzlů z DOM.

fputcsv() bude opravdu snadné zapisovat data do CSV.

Dejte dohromady:

// 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');
} 

Výstup:

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



  1. SYSDATETIME() vs GETDATE() v SQL Server:Jaký je rozdíl?

  2. Výmluvný:Volání Kam ve vztahu

  3. mysql:jak obejít implicitní potvrzení transakce?

  4. volání uloženého procesu přes dblink