2011-09-04 91 views
3

XML的DomDocument优化

我用下面的代码来获取所有的nodeValue

$dom  = new DomDocument('1.0', 'UTF-8'); 
if(!$dom->load($url)) 
return; 

$games = $dom->getElementsByTagName("game"); 
foreach($games as $game) 
{ 

} 

这需要76秒和有大约2000 games标签一个5MB的XML文件。有没有优化或其他解决方案来获取数据?

+0

我无法想象如何在不知道循环做什么的情况下优化循环。 – Herbert

+1

看看这个链接[此处输入链接的描述] [1] [1]:http://stackoverflow.com/questions/188414/best-xml-parser-for-php – steve

+1

@steve:也许你可以详细说明并以答案的形式提出。 SimpleXML如何加快循环以获取数据? – Herbert

回答

0

您不应该在大型XML文件上使用文档对象模型,它应该用于人类可读文档,而不是大数据集!

如果你想快速访问,你应该使用XMLReader或SimpleXML。

XMLReader是解析整个文档的理想选择,SimpleXML具有很好的XPath函数来快速检索数据。

有关的XMLReader,您可以使用下面的代码:

<?php 

// Parsing a large document with XMLReader with Expand - DOM/DOMXpath 
$reader = new XMLReader(); 

$reader->open("tooBig.xml"); 

while ($reader->read()) { 
    switch ($reader->nodeType) { 
     case (XMLREADER::ELEMENT): 
     if ($reader->localName == "game") { 
      $node = $reader->expand(); 
      $dom = new DomDocument(); 
      $n = $dom->importNode($node,true); 
      $dom->appendChild($n); 
      $xp = new DomXpath($dom); 
      $res = $xp->query("/game/title"); // this is an example 
      echo $res->item(0)->nodeValue; 
     } 
    } 
} 
?> 

上面会输出所有的游戏(假设你有/game/title XML结构)。

对于SimpleXML的,你可以使用:

$xml = file_get_contents($url); 
$sxml = new SimpleXML($xml); 
$games = $sxml->xpath('/game'); // returns an array of SXML nodes 
foreach ($games as $game) 
{ 
    print $game->nodeValue; 
} 
+0

感谢您的帮助。我有两个问题,比赛前的斜线是什么。和我怎样才能得到这个元素的字符串:对象(SimpleXMLElement)[8991] 字符串'手球'(长度= 8),我想要手球 –

+0

没有probs ...'/游戏中的斜线显示该文件。这就是XPath的工作原理(Google XPath了解更多信息)。为了回答你的第二个问题,我需要看到你正在使用的XML的一个例子。如果你编辑你的问题并粘贴它,我可以看到它。 – Alex

+0

SimpleXML还会加载整个文件,这完全不会提高速度。 DOM本身也支持XPath。 – cweiske

1

我曾经写了一篇博客文章关于loading huge XML files with XMLReader - 你或许可以用一些。

使用DOM或SimpleXML是没有选择的,因为都将整个文档加载到内存中。

+0

SimpleXml非常好,我测试过在一个xml文件中,DOM耗时约30秒,SimpleXML耗时1秒:) –

+0

SimpleXML已证明对于OP来说非常有用,并且DOM太慢 - 正如我所建议的。与SAX一起,XMLReader是最快的。 – Alex

0

您可以使用DOMXpath进行查询,这比方法DOMDocument:: getElementsByTagName()快。

<?php 
$xpath = new \DOMXpath($dom); 
$games = $xpath->query("//game"); 

foreach ($games as $game) { 
    // Code here 
} 

在我的一个相当大的文件测试之一,这种方法把< 1秒完成24K元件的迭代中,而DOMDocument:: getElementsByTagName()方法正在采取〜27分钟(和时间带进行迭代到下一个对象是指数)。