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"