sql >> Database >  >> RDS >> Mysql

Hoe krijg ik een zip-bestand van 50 MB met een xml-bestand van 600 MB in een mysql-gegevenstabel?

MySQL kent uw XML-structuur niet. Hoewel het eenvoudige, goed gevormde XML-structuren rechtstreeks kan importeren, moet u complexere structuren zelf converteren. U kunt CSV, SQL of een (ondersteunde) XML genereren.

Voor zulke grote bestanden is XMLReader de beste API. Maak eerst een instantie en open het bestand:

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

Je gebruikt naamruimten, dus ik raad aan om er een mapping array voor te definiëren:

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

Het is mogelijk om dezelfde prefixen/aliassen te gebruiken als in het XML-bestand, maar u kunt ook uw eigen prefixen/aliassen gebruiken.

Doorloop vervolgens de XML-knooppunten totdat u het eerste knooppunt van het recordelement vindt:

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

U moet de lokale naam (de tagnaam zonder het naamruimtevoorvoegsel) en de naamruimte-URI vergelijken. Op deze manier is uw programma niet afhankelijk van de feitelijke prefixen in het XML-bestand.

Nadat je het eerste knooppunt hebt gevonden, kun je naar de volgende broer of zus met dezelfde lokale naam gaan.

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

U kunt XMLReader gebruiken om de recordgegevens te lezen, maar het is gemakkelijker met DOM- en XPath-expressies. XMLReader kan het huidige knooppunt uitbreiden tot een DOM-knooppunt. Dus bereid een DOM-document voor, maak er een XPath-object voor en registreer de naamruimten. Als u een knooppunt uitbreidt, worden het knooppunt en alle afstammelingen in het geheugen geladen, maar niet de bovenliggende knooppunten of broers en zussen.

$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() stelt u in staat om Xpath-expressie te gebruiken om scalaire waarden of knooppuntlijsten van een DOM op te halen.

fputcsv() zal het echt gemakkelijk maken om de gegevens in een CSV te schrijven.

Samengevoegd:

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

Uitgang:

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



  1. Een gids voor MySQL Galera Cluster-streamingreplicatie:deel één

  2. Waarom krijg ik dat de MySQL-foutquery leeg was?

  3. Groeperen door een enorme toename van de uitvoeringstijd van query's te veroorzaken

  4. Vragen naar dingen in de buurt van een geolocatie?