PHP - 解析大型XML文件并删除重复节点

时间:2013-10-21 02:58:50

标签: php xml symfony

我有一个用Symfony 1编写的应用程序。 系统管理员每天都会上传一个包含新客户列表的XML。

就在最近,他们丢失了很多包含客户信息的数据库记录。

好消息是,该信息存储在其他地方(除了主数据库之外),因此他们能够生成包含所有客户数据的XML。

问题是这样的XML不仅很大(大约25MB),而且还有很多重复的节点。

它们用于上传更小的文件(大小为300kb),因为它们每天上传它们,因此在上传此文件时,它超过了PHP的默认30秒运行时间,导致脚本停止执行。

我想知道是否有一种快速处理此XML文件并使用PHP代码删除所有重复节点的方法。

XML具有以下格式

<?xml version="1.0" encoding="ISO-8859-1" ?>
 <Clientes>
  <Cliente>
  <clienteCodigo>1Z</clienteCodigo>
  <nombreCliente>COMPANY NAME</nombreCliente>
  <telefonoCliente>011-4444-4555</telefonoCliente>
  </Cliente>
  <Cliente>
  <clienteCodigo>1Z</clienteCodigo>
  <nombreCliente>COMPANY NAME</nombreCliente>
  <telefonoCliente>011-4444-4555</telefonoCliente>
  </Cliente>
  <Cliente>
  <clienteCodigo>2A</clienteCodigo>
  <nombreCliente>COMPANY NAME 2</nombreCliente>
  <telefonoCliente>011-8888-4646</telefonoCliente>
  </Cliente>
  <Cliente>
  <clienteCodigo>2A</clienteCodigo>
  <nombreCliente>COMPANY NAME 2</nombreCliente>
  <telefonoCliente>011-8888-4646</telefonoCliente>
  </Cliente>
 </Clientes>

提前致谢。

编辑:这是当前通过元素循环的代码(我没有写它)。

 foreach($clientes->getElementsByTagName("Cliente") as $clienteElement)

    { 

        $clienteNew = Doctrine::getTable('Cliente')->findOneByCliente_codigo($clienteElement->getElementsByTagName("clienteCodigo")->item(0)->nodeValue);

        if (!$clienteNew)

        {

            $clienteNew = new Cliente();               

            $clienteNew->cliente_codigo = $clienteElement->getElementsByTagName("clienteCodigo")->item(0)->nodeValue;            

        }

        $clienteNew->nombre = $clienteElement->getElementsByTagName("nombreCliente")->item(0)->nodeValue;    
        $clienteNew->telefono = $clienteElement->getElementsByTagName("telefonoCliente")->item(0)->nodeValue;        
        $clienteNew->save();                          
    }

1 个答案:

答案 0 :(得分:1)

尽管我是Symfony和Doctrine的忠实粉丝...对于那些插入,更新和检查最快的方式就是这样,使用php pdo:

  1. 在您想要唯一的列上设置唯一索引,并在当前代码中检查

  2. 伪代码:

    $conn = new \PDO("mysql:host= .... your connection string here");
    $conn->beginTransaction(); //this speeds up a lot
    $sql = "INSERT INTO tablename (field list) VALUES (parameters matching field list) ON DUPLICATE KEY UPDATE field=param pairs";
    
    foreach($clientes->getElementsByTagName("Cliente") as $clienteElement) {
        $q->execute(array(param => xml_value));
    }
    
    $conn->commit();
    
  3. 并且像这样你可以使用现在使用的代码处理更多数据。

    如果这没有帮助......那么您可以考虑延长运行php脚本的时间:http://php.net/function.set-time-limit