PHP XML解析-它能更快吗?
我有一个大的XML文件(400 MB),我需要每天更新它。对于每个主要元素,我都使用SELECT+INSERT/UPDATE查询到数据库中。当我运行脚本时,它每分钟处理26个主要元素,但速度变慢了——在500个主要元素之后,速度要慢得多(每分钟10个元素) 这是XML:PHP XML解析-它能更快吗?,php,xml,Php,Xml,我有一个大的XML文件(400 MB),我需要每天更新它。对于每个主要元素,我都使用SELECT+INSERT/UPDATE查询到数据库中。当我运行脚本时,它每分钟处理26个主要元素,但速度变慢了——在500个主要元素之后,速度要慢得多(每分钟10个元素) 这是XML: <?xml version="1.0" encoding="utf-8"?> <SHOP> <SHOPITEM> <ITEM_ID>26000003941
<?xml version="1.0" encoding="utf-8"?>
<SHOP>
<SHOPITEM>
<ITEM_ID>2600000394161</ITEM_ID>
(+ 15 more elements like this)
<PARAM>
<PARAM_NAME><![CDATA[some data here]]></PARAM_NAME>
<VAL><![CDATA[some data here]]></VAL>
</PARAM>
(+ 10 more elements like this)
</SHOPITEM>
(lot of shopitems here)
</SHOP>
2600000394161
(+15个以上类似元素)
(+10个以上类似元素)
(这里有很多商品)
由于内存问题,我无法使用SimpleXML。有没有更快的PHP XML解析器,或者用什么方法来比较大型站点(例如价格比较站点)?更好的硬件?XML处理时,我的CPU占用10%,RAM占用80%。我不能说DOMDocument方法是否比SimpleXML快,但要使用DOMDocument,您需要执行以下操作(未经测试):
通过将节点从XMLReader扩展到DOM元素节点,可以稍微加快XML解析的速度,元素节点可以转换为SimpleXMLElement
$xml_reader = new XMLReader;
$xml_reader->open("feed.xml");
$dom = new DOMDocument();
$xpath = new DOMXPath($dom);
// move the pointer to the first product
while ($xml_reader->read() && $xml_reader->name != 'SHOPITEM');
// loop through the products
while ($xml_reader->name == 'SHOPITEM') {
// expand to DOM element
$element = $xml_reader->expand($dom);
// use Xpath with the $element as context node
$itemId = $xpath->evaluate('string(ITEM_ID)', $element);
// or import it into a SimpleXMLElement
$item = simplexml_import_dom($element);
//SELECT, UPDATE/INSERT HERE
// move the pointer to the next product
$xml_reader->next('SHOPITEM');
}
// don’t forget to close the file
$xml_reader->close();
为了加快进程,您应该收集数据并进行大量插入。大多数数据库管理系统都以这样或那样的方式支持它。更少的SQL查询意味着更少的数据库工作,但您需要内存来收集数据。你必须找到一个平衡点
另一种可能是生成一个包含所有SQL语句的本地文件,并使用控制台客户端执行它。这可能非常快,但可能存在安全风险。考虑使用XML数据库(例如eXist或BaseX)。在这种规模下,它将更加高效。如果您的XML具有固定的结构,那么手动解析它只会更快。XML解析器是多用途的,它们将使用您实际需要的更多CPU和RAM。您可以发布一个示例或您的XML结构吗?听起来您应该先使用其他数据存储,然后再使用单个XML文件。至少可以拆分成多个文件,或者更可能的情况是,只使用一个DB。如果将XML重写为SQLite DB,它将运行得更快!值得思考的是…我对2GB+XML文件有一个问题,需要花太多时间来编辑。。我每天都要做。当它被重新编写为SQLite文件时,它从几分钟变成了几秒钟!(保存文件从2GB+增加到了10MB左右,令人惊讶)另外,我怀疑您的CPU是否有10%用于XML处理。。它可能是“100%(减去硬盘IO)的1核”,而您有8+个(逻辑)CPU核;)非常感谢。我会试试看,然后回答关于速度的问题。
$xmlfile='/path/to/feed.xml';
if( file_exists( $xmlfile ) ){
libxml_use_internal_errors( TRUE );
$dom = new DOMDocument('1.0','utf-8');
$dom->validateOnParse=false;
$dom->standalone=true;
$dom->preserveWhiteSpace=true;
$dom->strictErrorChecking=false;
$dom->substituteEntities=false;
$dom->recover=true;
$dom->formatOutput=false;
$dom->loadXML( $xmlfile );
$parse_errs=serialize( libxml_get_last_error() );
libxml_clear_errors();
$xpath=new DOMXPath( $dom );
$items = $dom->getELementsByTagName('SHOPITEM');
foreach( $items as $node ){
echo $node->nodeValue;
/* Each node is likely to have children */
$children=$xpath->query('PRODUCTNO',$node);
foreach( $children as $child ){
echo $child->nodeValue;
}
/*
mysql cmds
----------
select , update, insert
*/
}
$dom=null;
}
$xml_reader = new XMLReader;
$xml_reader->open("feed.xml");
$dom = new DOMDocument();
$xpath = new DOMXPath($dom);
// move the pointer to the first product
while ($xml_reader->read() && $xml_reader->name != 'SHOPITEM');
// loop through the products
while ($xml_reader->name == 'SHOPITEM') {
// expand to DOM element
$element = $xml_reader->expand($dom);
// use Xpath with the $element as context node
$itemId = $xpath->evaluate('string(ITEM_ID)', $element);
// or import it into a SimpleXMLElement
$item = simplexml_import_dom($element);
//SELECT, UPDATE/INSERT HERE
// move the pointer to the next product
$xml_reader->next('SHOPITEM');
}
// don’t forget to close the file
$xml_reader->close();