我试图利用PHP脚本将一个大型XML文件(约450 MB)解析为MYSQL数据库,并将其转化为包含XML元素的特定结构和定义。问题是,原始脚本使用file_get_contents和SimpleXMLElement来完成它,但是服务器执行的核心工作由于XML文件的数量而停止。我不是PHP专家,所以我买了这个XMLSplit软件,将XML分成17个独立的30 MB大小的XML文件,并使用相同的脚本逐一解析它们。但是,输出数据库丢失了大量的输入,我非常怀疑如果不自动分割和逐个解析,这是否是原始文件的相同输出。
因此,我决定使用XMLReader和这个精确的PHP脚本来解析这个大型的XML文件,但到目前为止,我还无法简单地替换解析代码并保持其他功能不变。
我包括下面的脚本,如果有人能帮我这么做,我会非常感激的。
<?php
set_time_limit(0);
ini_set('memory_limit', '1024M');
include_once('../db.php');
include_once(DOC_ROOT.'/include/func.php');
mysql_query("TRUNCATE screenshots_list");
mysql_query("TRUNCATE pages");
mysql_query("TRUNCATE page_screenshots");
$xmlstr = file_get_contents('t_info.xml');
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->template as $item)
{
//print_r($item);
$sql = sprintf("REPLACE INTO templates SET id = %d, state = %d, price = %d, exc_price = %d, inserted_date = '%s', update_date = '%s', downloads = %d, type_id = %d, type_name = '%s', is_flash = %d, is_adult = %d, width = '%s', author_id = %d, author_nick = '%s', package_id = %d, is_full_site = %d, is_real_size = %d, keywords = '%s', sources = '%s', description = '%s', software_required = '%s'", $item->id, $item->state, $item->price, $item->exc_price, $item->inserted_date, $item->update_date, $item->downloads, $item->template_type->type_id, $item->template_type->type_name, $item->is_flash, $item->is_adult, $item->width, $item->author->author_id, $item->author->author_nick, $item->package->package_id, $item->is_full_site, $item->is_real_size, $item->keywords, $item->sources, $item->description, $item->software_required);
//echo '<br>'.$sql;
mysql_query($sql);
//print_r($item->screenshots_list->screenshot);
foreach ($item->screenshots_list->screenshot as $scr) {
$main = (!empty($scr->main_preview)) ? 1 : 0;
$small = (!empty($scr->small_preview)) ? 1 : 0;
insert_data($item->id, 'screenshots_list', 0, $scr->uri, $scr->filemtime, $main, $small);
}
foreach ($item->styles->style as $st) {
insert_data($item->id, 'styles', $st->style_id, $st->style_name);
}
foreach ($item->categories->category as $cat) {
insert_data($item->id, 'categories', $cat->category_id, $cat->category_name);
}
foreach ($item->sources_available_list->source as $so) {
insert_data($item->id, 'sources_available_list', $so->source_id, '');
}
foreach ($item->software_required_list->software as $soft) {
insert_data($item->id, 'software_required_list', $soft->software_id, '');
}
//print_r($item->pages->page);
if (!empty($item->pages->page)) {
foreach ($item->pages->page as $p) {
mysql_query(sprintf("REPLACE INTO pages SET tpl_id = %d, name = '%s', id = NULL ", $item->id, $p->name));
$page_id = mysql_insert_id();
if (!empty($p->screenshots->scr)) {
foreach ($p->screenshots->scr as $psc) {
$href = (!empty($psc->href)) ? (string)$psc->href : '';
mysql_query(sprintf("REPLACE INTO page_screenshots SET page_id = %d, description = '%s', uri = '%s', scr_type_id = %d, width = %d, height = %d, href = '%s'", $page_id, $psc->description, $psc->uri, $psc->scr_type_id, $psc->width, $psc->height, $href));
}
}
}
}}?>为了突出显示所讨论的代码行,在不影响脚本其余部分功能的情况下,我尝试用XMLReader方法替换代码行:
$xmlstr = file_get_contents('t_info.xml');
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->template as $item) {我很感激你的解决方案..。
发布于 2014-06-06 14:59:10
可以将XML读取器位置扩展到DOMElement。此元素不与DOMDocument相关联,因此不能直接转换为SimpleXMLElement,但可以导入到DOMDocument中。
$xml = <<<'XML'
<templates>
<template>
<styles>
<style>TEST</style>
</styles>
</template>
</templates>
XML;
$reader = new XMLReader;
$reader->open('data://text/xml;base64,'.base64_encode($xml));
$dom = new DOMDocument;
// look for the first template element
while ($reader->read() && $reader->localName !== 'template') {
continue;
}
// while you have an template element
while ($reader->localName === 'template') {
// convert to SimpleXMLElement
$element = simplexml_import_dom(
// expand to a DOMElement in the prepared document object
$reader->expand($dom)
);
var_dump(
$element
);
// move to the next template sibling
$reader->next('template');
}输出:
object(SimpleXMLElement)#3 (1) {
["styles"]=>
object(SimpleXMLElement)#4 (1) {
["style"]=>
string(4) "TEST"
}
}我通常使用DOM+Xpath,不将其转换为SimpleXML,但是这种方法对于您的问题应该很好。
https://stackoverflow.com/questions/24084203
复制相似问题