Texan78
Texan78

Reputation: 687

Remove duplicates from SimpleXML Object

I was hoping I could get some help with something I am struggling with. I parsing an XML feed with SimpleXML but, I am trying to remove the duplicates.

I have done a lot of research and can't seem to get this sorted. Best approach would be array_unique I think but, the variable $event which contains the output from the parse doesn't seem to work with it.

Link to the script http://www.mesquiteweather.net/inc/inc-legend.php

Code I am using. Any help would be greatly appreciated. I have spent several days trying to resolve this.

// Lets parse the data
$entries = simplexml_load_file($data);
if(count($entries)):
    //Registering NameSpace
    $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
    $result = $entries->xpath("//prefix:entry");

    foreach ($result as $entry):
        $event = $entry->children("cap", true)->event;

        endforeach;
endif;

// Lets creat some styles for the list
    $legendStyle = "margin:10px auto 10px auto;";

$legend .= "<table style='$legendStyle' cellspacing='5px'>";
$legend .= "<tr>";

$i = 1;
foreach ($result as $entry) {
    $event = $entry->children("cap", true)->event;
//Set the alert colors for the legend
   include ('../inc-NWR-alert-colors.php');
   $spanStyle   = "background-color:{$alertColor};border:solid 1px #333;width:15px;height:10px;display:inline-block;'> </span><span style='font-size:12px;color:#555;";
    $legend .= "<td> <span style='$spanStyle'> $event</span></td>";
    if($i % 5 == 0)
        $legend .= "</tr><tr>";
    $i++;
}

$legend .= "</tr>";
$legend .= "</table>";


echo $legend;

Upvotes: 1

Views: 1050

Answers (1)

user3942918
user3942918

Reputation: 26375

The example below uses the DOM instead of SimpleXML as the DOM provides the handy method C14N() to create canonical XML.

The basic idea of creating canonical XML is that two nodes that are effectively identical will have the same serialized output, regardless of their representation in the source document.

For example attribute order doesn't matter on an element, so both:

<element foo="Foo" bar="Bar"/>`

and:

<element bar="Bar" foo="Foo"/>

are effectively identical. Canonicalize them and the resulting XML for each will be:

<element bar="Bar" foo="Foo"></element>

If you iterate over your desired elements to create an array and use their canonical representations as keys, you'll end up with an array of unique nodes.


Example:

$dom = new DOMDocument();
$dom->load("http://alerts.weather.gov/cap/ca.atom");

// Create an array of unique events
$events = [];
foreach ($dom->getElementsByTagNameNS("urn:oasis:names:tc:emergency:cap:1.1", "event") as $event) {
    $events[$event->C14N()] = $event;
}

// ... do whatever other stuff you need ...

// Output event text.
foreach ($events as $event) {
    echo "$event->nodeValue\n";
}

Output:

Coastal Flood Advisory
High Surf Advisory
Wind Advisory
Winter Weather Advisory
Beach Hazards Statement

Upvotes: 1

Related Questions