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"