MySQL не познава вашата XML структура. Въпреки че може директно да импортира прости, добре оформени XML структури, ще трябва сами да конвертирате по-сложни структури. Можете да генерирате CSV, SQL или (поддържан) XML.
За големи файлове като този XMLReader е най-добрият API. Първо създайте екземпляр и отворете файла:
$reader = new XMLReader();
$reader->open('php://stdin');
Вие използвате пространства от имена, така че предлагам да дефинирате масив за съпоставяне за тях:
$xmlns = [
'a' => 'http://www.abc-example.com'
];
Възможно е да използвате същите префикси/псевдоними като в XML файла, но можете да използвате и свои собствени.
След това преминете през XML възлите, докато намерите първия възел на записния елемент:
while (
$reader->read() &&
($reader->localName !== 'ABCRecord' || $reader->namespaceURI !== $xmlns['a'])
) {
continue;
}
Трябва да сравните локалното име (името на етикета без префикса на пространството от имена) и URI на пространството от имена. По този начин програмирането ви не зависи от действителните префикси в 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 възел. Затова подгответе 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()
ви позволява да използвате Xpath израз за извличане на скаларни стойности или списъци с възли от DOM.
fputcsv()
ще направи ли наистина лесно записването на данните в CSV.
Съберете заедно:
// 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"