Question

I'm pulling data from an XML file using the following code:

<?php
$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);

foreach($xml as $Reader) { 
    $items[] = $Reader; 
}
usort ($items, function($a, $b) { 
    return strcmp($a->Status,$b->Status); 
});

foreach($items as $Reader) { 
    if($Reader->Status != 'Logged Off' && $Reader->Picture != 'None')
        {
        include '/extras/reader-single.php';
        }
}

?>

The two lines showing $exclude and $items I've added afer seeing another post excluding values from a foreach loop about excluding from XML, but when i load the page.. the two records that have the PINs specified, are still showing.

Is this the correct way to exclude pulling certain records from an XML file?

Any help is greatly appreciated!

EDIT: The four digit numbers entered are a PIN number found at Reader->PIN After thinking, could it be that it's not making the link between the number and the Reader->PIN on the xml file?

Was it helpful?

Solution 2

As I told in comments, get the pin of each record, compare it to the exclude array, if it is part of the exclude array then just continue the loop. Like this:

$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);

foreach($xml as $Reader) { 
    $items[] = $Reader; 
}

usort ($items, function($a, $b) { 
    return strcmp($a->Status,$b->Status); 
});

foreach($xml as $Reader) { 
    if($Reader->Status != 'Logged Off'
        && $Reader->Picture != 'None'
        // check if the Pin is in exclude array
        && !in_array($Reader->Pin, $exclude)
    ) { 
        include '/extras/reader-single.php';
    }   
}

Alternatively you may use array_filter():

$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);

foreach($xml as $Reader) { 
    $items[] = $Reader; 
}

$items= array_filter($items, function($Reader) use ($exclude) {
    if($Reader->Status == 'Logged Off'
       || $Reader->Picture == 'None'
       || in_array($Reader->Pin, $exclude)
    ) { 
        return false;
    }   
    return true;
});

usort ($items, function($a, $b) {
    return strcmp($a->Status,$b->Status);
});

foreach($items as $Reader) {
    include '/extras/reader-single.php'; 
}

OTHER TIPS

There is a much simpler way to specifically query for attributes - or to exclude them.

$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$matches = $xml->xpath( "//Reader[Pin!=4419 and Pin!=4373]" );

This will give you the entire structure, minus the two items # 4419 and # 4373.

Another way would be filter them out in the first foreach loop:

foreach($xml as $Reader) {
    if (array_search($Reader->Pin, $exclude) === FALSE) {
         $items[] = $Reader;
    }
}

In either case, you do not need:

$items = array_diff($items, $exclude);

array_diff() returns the values from the first array ($items) that do not exist in the second array ($exclude). Because in your case the first array is an empty array, it has no values, so array_diff() will also always return an empty array.

Perhaps someone will come along with an XPath solution - that would be another approach. (EDIT - Ah, I see @pp19dd has supplied this.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top