1

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;
jophab
  • 5,356
  • 14
  • 41
  • 60
Texan78
  • 687
  • 2
  • 16
  • 42
  • one way of dealing with this is to have a unique set of values first (normally contained inside an array), before presenting it. by they way, do you have a sample xml link? – Kevin Dec 20 '14 at 04:53
  • @ghost here is the feed I am using to test http://alerts.weather.gov/cap/CA.atom You are correct about having it in an array first and I agree. It appears to be when I print it but, it is unique since it is not a normal XML has it uses a namespace. I am having trouble with getting it into an array that can be useable. – Texan78 Dec 20 '14 at 05:46
  • @Texan78 wait a minute, whats supposed to be the correct final output? your PHP site, has 15 results right? whats the correct number? – Kevin Dec 20 '14 at 06:32

1 Answers1

1

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
user3942918
  • 25,539
  • 11
  • 55
  • 67
  • That's great and it works and I like that way better but, now I am back to square one with it being unformatted with my styling. I.E. in a table that produces 5 columns then starts a new row. – Texan78 Dec 20 '14 at 06:58