Jump to content

SimpleXML Question


Texan78
Go to solution Solved by QuickOldCar,

Recommended Posts

Hello, I am sorry for this question in advance. I will try to explain it as detailed but, as short as possible so bare with me. I have a script that I did that parses an XML file and outputs the info in a table. The tables are created with each entry in XML file. Everything works great and as designed except for when there is no data. I know why it is doing this, I am just not sure how to approach fixing this. So here is what the data looks like where there is nothing and what the table shows. I am posting a screenshot of the XML file as I am not sure it will be empty if I post the link. 

 

zsffVF.png
 
63ohLB.png
 
 
Here is what it is suppose to look like taken from another script using the same method. 
 
4Fj1iO.png
 
 
Now this is happening because summary any some of the variables from the XML in the php isn't empty, so it is producing the table with broken data that doesn't exist because it thinks that XML has data in it because of how the XML is construct, it really isn't empty. So is there a way I can check one of the variables that if it is empty then show the noStormMessage table instead of the table that thinks there is data when there really isn't?
 
I hope I explained this good enough. If not forgive me and I will try to explain it or answer any questions you might have.    

 

Here is the code I am working with for that script, just the relevant logic, not the styling and settings that is above this part. 

//Set initial output to false
$tData = false;
$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):
        $updated = $entry->updated;
        $Updated = date("D, M d, g:i a", strtotime($updated));
        $summary = $entry->summary;
  // Replaces all triple periods with single periods
        $summary = trim(str_replace('...', '.', $summary), '.') . '.';
  //now capitalize every letter after a . ? and ! followed by space
        $Summary = preg_replace_callback('/([.!?*])\s*(\w)/', function ($matches) {
            return strtoupper($matches[1] . ' ' . $matches[2]);
            }, ucfirst(strtolower($summary)));
        $event = $entry->children("cap", true)->event;
        $effective = $entry->children("cap", true)->effective;
        $expires = $entry->children("cap", true)->expires;
        $updated = $entry->children("cap", true)->updated;
        $updateDate = date("D, M d, g:i a", strtotime($updated));
        $effectiveDate = date("D, M d, g:i a", strtotime($effective));
        $expiresDate = date("D, M d, g:i a", strtotime($expires));
        $status = $entry->children("cap", true)->status;
        $severity = $entry->children("cap", true)->severity;
        $urgency = $entry->children("cap", true)->urgency;
        $area = $entry->children("cap", true)->areaDesc;

        include ('inc-alert-colors.php');

// Let's assign the table some styles
   $tableStyle = "width: 100%; margin:0px auto; background-color:{$bkgColor};";
   $td1Style = "{$tbrdr};{$sbrdr}; padding:2px 0px 2px 6px;  background-image:url({$imagesDir}headerbgd2.gif); color:{$dtColor};";
   $td2Style = "{$sbrdr}; padding:6px 0px 0px 6px; background-color:{$alertColor};";
   $td3Style = "{$sbrdr}; line-height:5px; background-color:{$alertColor};";
   $td4Style = "{$sbrdr}; {$bbrdr}; padding: 2px 6px 6px 6px; background-color:{$alertColor};";

// construct data for table display
    $tData .= "<table style='{$tableStyle}' cellpadding='0' cellspacing='0'>\n";
    $tData .= "<tbody>\n";
    $tData .= "  <tr><td style='{$td1Style}'><b>{$event}</b> <div style='float:right'><b>Updated: {$Updated}</b></div></td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td2Style}'>Effective: <b>{$effectiveDate}</b>   -   Expires: <b>{$expiresDate}</b>   -   Status: <b>{$status}</b>   -   Severity: <b>{$severity}</b>   -   Urgency: <b>{$urgency}</b></td>\n";
    $tData .= "  </tr>\n";
    $tData .= "  <tr><td style='{$td3Style}'> </td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'>Issued For: <b>{$area}</b></td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'><strong>Summary:</strong> {$Summary}</td></tr>\n";
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
    $tData .=  $afterTable;

       endforeach;
endif;

//If no storms were in the source, set no storm message
if(!$tData)
{
    $tData = $noStormMessage;
}

echo $tData;

?>

-Thanks!

Link to comment
Share on other sites

You can add an error if anything was blank to show your default message.

Since you populated $tdata with html it always has values.

 

Just add an $error variable to anything missing, then check for $error to determine your custom message.

//Set initial output to false
$tData = false;
$entries = simplexml_load_file($data);
if(count($entries)):
    //Registering NameSpace
    $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
    $result = $entries->xpath("//prefix:entry");
if(!$result){
$error = true;
}
    foreach ($result as $entry):
        $updated = $entry->updated;
if($updated == ''){
$error = true;
}

        $Updated = date("D, M d, g:i a", strtotime($updated));
        $summary = $entry->summary;
if($summary == ''){
$error = true;
}

  // Replaces all triple periods with single periods
        $summary = trim(str_replace('...', '.', $summary), '.') . '.';
  //now capitalize every letter after a . ? and ! followed by space
        $Summary = preg_replace_callback('/([.!?*])\s*(\w)/', function ($matches) {
            return strtoupper($matches[1] . ' ' . $matches[2]);
            }, ucfirst(strtolower($summary)));
        $event = $entry->children("cap", true)->event;
if($event == ''){
$error = true;
}

        $effective = $entry->children("cap", true)->effective;
        $expires = $entry->children("cap", true)->expires;
        $updated = $entry->children("cap", true)->updated;
        $updateDate = date("D, M d, g:i a", strtotime($updated));
        $effectiveDate = date("D, M d, g:i a", strtotime($effective));
        $expiresDate = date("D, M d, g:i a", strtotime($expires));
        $status = $entry->children("cap", true)->status;
        $severity = $entry->children("cap", true)->severity;
        $urgency = $entry->children("cap", true)->urgency;
        $area = $entry->children("cap", true)->areaDesc;
        include ('inc-alert-colors.php');// Let's assign the table some styles
   $tableStyle = "width: 100%; margin:0px auto; background-color:{$bkgColor};";
   $td1Style = "{$tbrdr};{$sbrdr}; padding:2px 0px 2px 6px;  background-image:url({$imagesDir}headerbgd2.gif); color:{$dtColor};";
   $td2Style = "{$sbrdr}; padding:6px 0px 0px 6px; background-color:{$alertColor};";
   $td3Style = "{$sbrdr}; line-height:5px; background-color:{$alertColor};";
   $td4Style = "{$sbrdr}; {$bbrdr}; padding: 2px 6px 6px 6px; background-color:{$alertColor};";// construct data for table display
    $tData .= "<table style='{$tableStyle}' cellpadding='0' cellspacing='0'>\n";
    $tData .= "<tbody>\n";
    $tData .= "  <tr><td style='{$td1Style}'><b>{$event}</b> <div style='float:right'><b>Updated: {$Updated}</b></div></td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td2Style}'>Effective: <b>{$effectiveDate}</b>   -   Expires: <b>{$expiresDate}</b>   -   Status: <b>{$status}</b>   -   Severity: <b>{$severity}</b>   -   Urgency: <b>{$urgency}</b></td>\n";
    $tData .= "  </tr>\n";
    $tData .= "  <tr><td style='{$td3Style}'> </td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'>Issued For: <b>{$area}</b></td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'><strong>Summary:</strong> {$Summary}</td></tr>\n";
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
    $tData .=  $afterTable;       endforeach;
endif;
//If no storms were in the source, set no storm message
if($error)
{
    $tData = $noStormMessage;
}
echo $tData;
Link to comment
Share on other sites

Thank you, that appears to work, but there is no style assigned to it. Since Updated and Summary will never be empty from the XML is it possible to check different variables and if those are empty them show my normal styled no storm message? I tried playing around with exchanging it with empty variables but it threw undefined error for summary and updated. Is that because those are the entry points and I was using childs to check maybe?

 

 

-Thanks

Link to comment
Share on other sites

There is, that is what $tData is. 

// Let's assign the table some styles
   $tableStyle = "width: 100%; margin:0px auto; background-color:{$bkgColor};";
   $td1Style = "{$tbrdr};{$sbrdr}; padding:2px 0px 2px 6px;  background-image:url({$imagesDir}headerbgd2.gif); color:{$dtColor};";
   $td2Style = "{$sbrdr}; padding:6px 0px 0px 6px; background-color:{$alertColor};";
   $td3Style = "{$sbrdr}; line-height:5px; background-color:{$alertColor};";
   $td4Style = "{$sbrdr}; {$bbrdr}; padding: 2px 6px 6px 6px; background-color:{$alertColor};";

// construct data for table display
    $tData .= "<table style='{$tableStyle}' cellpadding='0' cellspacing='0'>\n";
    $tData .= "<tbody>\n";
    $tData .= "  <tr><td style='{$td1Style}'><b>{$event}</b> <div style='float:right'><b>Updated: {$Updated}</b></div></td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td2Style}'>Effective: <b>{$effectiveDate}</b>   -   Expires: <b>{$expiresDate}</b>   -   Status: <b>{$status}</b>   -   Severity: <b>{$severity}</b>   -   Urgency: <b>{$urgency}</b></td>\n";
    $tData .= "  </tr>\n";
    $tData .= "  <tr><td style='{$td3Style}'> </td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'>Issued For: <b>{$area}</b></td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'><strong>Summary:</strong> {$Summary}</td></tr>\n";
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
    $tData .=  $afterTable;

       endforeach;
endif;

//If no storms were in the source, set no storm message
if(!$tData)
{
    $tData = $noStormMessage;
}

echo $tData;
Link to comment
Share on other sites

  • Solution

$tData is replaced with $noStormMessage along with your style.

 

Is a pile of ways you can go about this, here is just one of them.

 

I have no idea what the value of $noStormMessage is, but you can add any style you wish or any tr,td

//Set initial output to false
$tData = false;
$entries = simplexml_load_file($data);
if(count($entries)):
    //Registering NameSpace
    $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
    $result = $entries->xpath("//prefix:entry");
if(!$result){
$error = true;
}
    foreach ($result as $entry):
        $updated = $entry->updated;
if($updated == ''){
$error = true;
}
        $Updated = date("D, M d, g:i a", strtotime($updated));
        $summary = $entry->summary;
if($summary == ''){
$error = true;
}  // Replaces all triple periods with single periods
        $summary = trim(str_replace('...', '.', $summary), '.') . '.';
  //now capitalize every letter after a . ? and ! followed by space
        $Summary = preg_replace_callback('/([.!?*])\s*(\w)/', function ($matches) {
            return strtoupper($matches[1] . ' ' . $matches[2]);
            }, ucfirst(strtolower($summary)));
        $event = $entry->children("cap", true)->event;
if($event == ''){
$error = true;
}        $effective = $entry->children("cap", true)->effective;
        $expires = $entry->children("cap", true)->expires;
        $updated = $entry->children("cap", true)->updated;
        $updateDate = date("D, M d, g:i a", strtotime($updated));
        $effectiveDate = date("D, M d, g:i a", strtotime($effective));
        $expiresDate = date("D, M d, g:i a", strtotime($expires));
        $status = $entry->children("cap", true)->status;
        $severity = $entry->children("cap", true)->severity;
        $urgency = $entry->children("cap", true)->urgency;
        $area = $entry->children("cap", true)->areaDesc;
        include ('inc-alert-colors.php');// Let's assign the table some styles
   $tableStyle = "width: 100%; margin:0px auto; background-color:{$bkgColor};";
   $td1Style = "{$tbrdr};{$sbrdr}; padding:2px 0px 2px 6px;  background-image:url({$imagesDir}headerbgd2.gif); color:{$dtColor};";
   $td2Style = "{$sbrdr}; padding:6px 0px 0px 6px; background-color:{$alertColor};";
   $td3Style = "{$sbrdr}; line-height:5px; background-color:{$alertColor};";
   $td4Style = "{$sbrdr}; {$bbrdr}; padding: 2px 6px 6px 6px; background-color:{$alertColor};";// construct data for table display
    $tData .= "<table style='{$tableStyle}' cellpadding='0' cellspacing='0'>\n";
    $tData .= "<tbody>\n";
//If no storms were in the source, set no storm message
if($error) {
    $tData .= $noStormMessage;
} else {
    $tData .= "  <tr><td style='{$td1Style}'><b>{$event}</b> <div style='float:right'><b>Updated: {$Updated}</b></div></td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td2Style}'>Effective: <b>{$effectiveDate}</b>   -   Expires: <b>{$expiresDate}</b>   -   Status: <b>{$status}</b>   -   Severity: <b>{$severity}</b>   -   Urgency: <b>{$urgency}</b></td>\n";
    $tData .= "  </tr>\n";
    $tData .= "  <tr><td style='{$td3Style}'> </td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'>Issued For: <b>{$area}</b></td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'><strong>Summary:</strong> {$Summary}</td></tr>\n";
}
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
    $tData .=  $afterTable;       endforeach;
endif;

echo $tData;
Edited by QuickOldCar
Link to comment
Share on other sites

Thank you so much for you help and jarring my dead brain. Here is what I ended up doing once I realized what you were saying. 

 

 

The value of $noStormMessage = There are currently no active watches, warnings or advisories. Which is what is produced from the XML $summary variable. Which when styled looks like this below. 

 

9WWupx.png

 

This is what I ended up doing with your help. Since $noStormMessage is just a variable with data. I created a table around it to display where I wanted it. Since you suggested the if/else statement that made sense and what I was looking to do. 

 

Thanks again for all your help!

// If no storms were in the source, set no storm message
if($error) {
    $tData .= "  <tr><td style='{$td1Style}; text-align:center;'>NWS WATCHES/WARNINGS/ADVISORIES</td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td5Style}'>{$noStormMessage}</td>\n";
    $tData .= "  </tr>\n";
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
} else {
    $tData .= "  <tr><td style='{$td1Style};'><b>{$event}</b> <div style='float:right'><b>Updated: {$Updated}</b></div></td></tr>\n";
    $tData .= "  <tr>\n";
    $tData .= "    <td style='{$td2Style}'>Effective: <b>{$effectiveDate}</b>   -   Expires: <b>{$expiresDate}</b>   -   Status: <b>{$status}</b>   -   Severity: <b>{$severity}</b>   -   Urgency: <b>{$urgency}</b></td>\n";
    $tData .= "  </tr>\n";
    $tData .= "  <tr><td style='{$td3Style}'> </td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'>Issued For: <b>{$area}</b></td></tr>\n";
    $tData .= "  <tr><td style='{$td4Style}'><strong>Summary:</strong> {$Summary}</td></tr>\n";
}
    $tData .= "</tbody>\n";
    $tData .= "</table>\n";
    $tData .=  $afterTable;       endforeach;
endif;

echo $tData;
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.