MySQL không biết cấu trúc XML của bạn. Mặc dù nó có thể nhập trực tiếp các cấu trúc XML đơn giản, được định dạng tốt, nhưng bạn sẽ cần phải tự mình chuyển đổi các cấu trúc phức tạp hơn. Bạn có thể tạo CSV, SQL hoặc XML (được hỗ trợ).
Đối với các tệp lớn như vậy, XMLReader là API tốt nhất. Trước tiên, hãy tạo một phiên bản và mở tệp:
$reader = new XMLReader();
$reader->open('php://stdin');
Bạn đang sử dụng không gian tên, vì vậy tôi khuyên bạn nên xác định một mảng ánh xạ cho chúng:
$xmlns = [
'a' => 'http://www.abc-example.com'
];
Có thể sử dụng các tiền tố / bí danh giống như trong tệp XML, nhưng bạn cũng có thể sử dụng tiền tố / bí danh của riêng mình.
Tiếp theo lướt qua các nút XML cho đến khi bạn tìm thấy nút phần tử bản ghi đầu tiên:
while (
$reader->read() &&
($reader->localName !== 'ABCRecord' || $reader->namespaceURI !== $xmlns['a'])
) {
continue;
}
Bạn cần so sánh tên cục bộ (tên thẻ không có tiền tố vùng tên) và URI vùng tên. Bằng cách này, bạn lập trình không phụ thuộc vào các tiền tố thực tế trong tệp XML.
Sau khi bạn tìm thấy nút đầu tiên, bạn có thể chuyển sang nút anh em tiếp theo có cùng tên cục bộ.
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');
}
Bạn có thể sử dụng XMLReader để đọc dữ liệu bản ghi nhưng dễ dàng hơn với các biểu thức DOM và XPath. XMLReader có thể mở rộng nút hiện tại thành một nút DOM. Vì vậy, hãy chuẩn bị một tài liệu DOM, tạo một đối tượng XPath cho nó và đăng ký các không gian tên. Mở rộng một nút sẽ tải nút và tất cả các nút con vào bộ nhớ, nhưng không tải các nút cha hoặc anh chị em.
$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()
cho phép bạn sử dụng biểu thức Xpath để tìm nạp các giá trị vô hướng hoặc danh sách nút từ DOM.
fputcsv()
nó sẽ giúp bạn thực sự dễ dàng ghi dữ liệu vào CSV.
Kết hợp với nhau:
// 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');
}
Đầu ra:
id,name
5967007LIEEXZX4LPK21,"REGISTERENHETEN I Bornheim"
5967007LIE45ZX4MHC90,"SUNNDAL HOSTBANK"