首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在特定的PHP代码中用XMLReader替换解析函数

在特定的PHP代码中用XMLReader替换解析函数
EN

Stack Overflow用户
提问于 2014-06-06 14:26:49
回答 1查看 210关注 0票数 0

我试图利用PHP脚本将一个大型XML文件(约450 MB)解析为MYSQL数据库,并将其转化为包含XML元素的特定结构和定义。问题是,原始脚本使用file_get_contentsSimpleXMLElement来完成它,但是服务器执行的核心工作由于XML文件的数量而停止。我不是PHP专家,所以我买了这个XMLSplit软件,将XML分成17个独立的30 MB大小的XML文件,并使用相同的脚本逐一解析它们。但是,输出数据库丢失了大量的输入,我非常怀疑如果不自动分割和逐个解析,这是否是原始文件的相同输出。

因此,我决定使用XMLReader和这个精确的PHP脚本来解析这个大型的XML文件,但到目前为止,我还无法简单地替换解析代码并保持其他功能不变。

我包括下面的脚本,如果有人能帮我这么做,我会非常感激的。

代码语言:javascript
复制
<?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方法替换代码行:

代码语言:javascript
复制
   $xmlstr = file_get_contents('t_info.xml');
   $xml = new SimpleXMLElement($xmlstr);
   foreach ($xml->template as $item) {

我很感激你的解决方案..。

EN

回答 1

Stack Overflow用户

发布于 2014-06-06 14:59:10

可以将XML读取器位置扩展到DOMElement。此元素不与DOMDocument相关联,因此不能直接转换为SimpleXMLElement,但可以导入到DOMDocument中。

代码语言:javascript
复制
$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');
}

输出:

代码语言:javascript
复制
object(SimpleXMLElement)#3 (1) {
  ["styles"]=>
  object(SimpleXMLElement)#4 (1) {
    ["style"]=>
    string(4) "TEST"
  }
}

我通常使用DOM+Xpath,不将其转换为SimpleXML,但是这种方法对于您的问题应该很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24084203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档