PHP Reading XML File with Preg_match_all
I am stuck on something I can't get my head around. Basically I have XML files that need to be read when they are submmitted. I am looking specifically for lines that include:
bytes="345354" I want to extract the int from the bytes tag and add them all up.
The current piece of code I am using does the trick but there is a problem. The code I am using at the moment is:
preg_match_all('|bytes="(.+?)"|', $filecontent, $array);
function arraySumRecursive($array)
{
$total = 0;
foreach(new recursiveIteratorIterator( new recursiveArrayIterator($array)) as $num)
{
$total += $num;
}
return $total;
}
$size = arraySumRecursive($array);
Now this code works all good but it has a problem once it reads an XML file with bytes that add up over 2537792398, it wont't display the correct sum of bytes but always stops at 2537792398 bytes. Granted the XML files are larger but I tested with an XML file with 2 lines and each line has a byte value of greater than 2537792398 and it still only shows 2537792398 bytes as the total sum.
Can anyone tell me what I am doing wrong? I personally have a feeling it has something to with the multi dimensional array but this code is the only one that worked and managed to grab the data for bytes="" . I haven't been able to use any other method of extracting the values and adding 开发者_StackOverflow中文版them all up to come up with one long byte number.
Any help or pointers in the right direction is appreciated!
Regards,
Tom
It sounds like your number is being read as a string, this happens to numbers when you use regex on them. You can use (int)$num to force it back into a number.
However, you should never use preg on xml you should use DOMDocument (simpleXML works too but my fav is DOMDOcument)
For ex. if your bytes attributes were on a bytestore xml node you would do:
$bytes = (int)0;
$xml = new DOMDocument();
$xml->load($variableholdingxml); //can be url of xml file also
foreach($xml->getElementsByTagName('bytestore') as $holder)
{
$bytes = $bytes + (int)$holder->getAttribute('bytes');
}
return $bytes;
Added in response to comment It usually does take a bit of time to parse large files, although I am no expert on the speed of DOMDocument methods xpath querying may be slightly quicker.
$xml = new DOMDocument();
$xml->load($variableholdingxml); //can be url of xml file also
$xpath = new DOMXPath();
$q = "//root/parentnode/childnode/byteholdnode/";
$nodes = $xpath->query($q);
foreach($nodes as $node)
{
$bytes = $bytes + (int)$node->getAttribute('bytes');
}
If your bytes attribute is in a byteholder node within a weholdbytes here node, with sub-trees of the tree's root the query would be:
$q = "//root/subtrees/weholdbytes/byteholder/"; /* yes that was supposed to make it clearer.*/
Anyway, give me a shout in the comments if you need any more help.
I agree, you need to use Dom in place of preg functions. XMl will always contain custom content, preg is not ready for this, besides, xml already has its parsers, the main dom idea, read the manual - http://lv.php.net/manual/en/class.domdocument.php
精彩评论