XML Skip 'wrong' event type - php

I have a certain BLOATED XML file that i use to generate a Gallery with some few information about the Picture. Besides of the Actual needed NEW there are plenty of entries with OLD, adding more pictures, but creating also duplicate entries.
<result>
<event>
<date>2015-04-14T22:19:02+02:00</date>
<type>OLD</type>
<value1>AAA</value1>
<id>changingIDwhatever</id>
<profile>
<url>/domainpart/SPECIFICNAME/?w=</url>
<name>SPECIFICNAME</name>
<value2>BBB</value2>
<value3>CCC</value3>
<value4>DDD</value4>
<image>
<url>http://domain.tld/path/to/the/image/320.jpg?1234-ab1cd2e345fg6789</url>
<width>320</width>
</image>
</profile>
</event>
<event>
<date>2015-04-14T22:19:02+02:00</date>
<type>NEW</type>
<value1>AAA</value1>
<id>changingIDwhatever</id>
<profile>
<url>/domainpart/ANOTHERNAME/?w=</url>
<name>ANOTHERNAME</name>
<value2>BBB</value2>
<value3>CCC</value3>
<value4>DDD</value4>
<image>
<url>http://domain.tld/path/to/the/image/320.jpg?1234-ab1cd2e345fg6789</url>
<width>320</width>
</image>
</profile>
</event>
<event>
<date>2015-04-14T22:19:02+02:00</date>
<type>NEW</type>
<value1>AAA</value1>
<id>changingIDwhatever</id>
<profile>
<url>/domainpart/SPECIFICNAME/?w=</url>
<name>SPECIFICNAME</name>
<value2>BBB</value2>
<value3>CCC</value3>
<value4>DDD</value4>
<image>
<url>http://domain.tld/path/to/the/image/320.jpg?1234-ab1cd2e345fg6789</url>
<width>320</width>
</image>
</profile>
</event>
</result>
I do generate everything in a pretty neat layout in a very basic way. As i have really NO knowledge at all about php, i usually base on skriptpieces i find that are kind of put together in a way that the outcome mostly is the way i need it.
<?php
//###################Config Start#########################
$memberid = "123456";
$maxAnzahl = 50;
$zaehler = 0;
$baseURL = "http://www.domain.tld";
//###################Config End#########################
$feed = simplexml_load_file('http://key:keypass#www.domain.tld/news/xml');
$events = $feed->events;
foreach ($events->event as $event) {
echo "<div class='4u'>";
echo "<article class='box style2'>";
if ($event->type == "newMember") {
echo "<a href='".$baseURL.$event->profile->url.$memberid."' class='image featured' target='_blank'><img src='" . $event->profile->image->url . "' alt='' /> </a>";
} else {
echo "<a href='".$baseURL.$event->profile->url.$memberid."' class='image featured' target='_blank'><img src='" . $event->image->url . "' alt='' /> </a>";
}
echo "<h3><a href='".$baseURL.$event->profile->url.$memberid."'>" . $event->profile->name . "</a></h3>";
echo "</article>";
echo "</div>";
$zaehler = $zaehler + 1;
if ($zaehler == $maxAnzahl) {
break;
}
}
?>
Would be someone able to tell me how i could specify now in that skript how to SKIP all OLD ?
Kind Regards
Caylean

I have found the solution myself sigh I was blind to it, till i got the first reply, checked my question AGAIN and saw a marker that I normally wanted to change everywhere to make it CLEAR what i needed.
In my initial question was a line "if ($event->type == "newMember") {" Normally i had to change it to "NEW" like in my example, to help ppl who wanted to help, to see it more easy.... Well, now i saw it and it made everything clear to me.
Changing the code like:
<?php
//###################Config Start#########################
$memberid = "123456";
$maxAnzahl = 50;
$zaehler = 0;
$baseURL = "http://www.domain.tld";
//###################Config End#########################
$feed = simplexml_load_file('http://key:keypass#www.domain.tld/news/xml');
$events = $feed->events;
foreach ($events->event as $event) {
if ($event->type == "NEW") {
echo "<div class='4u'>";
echo "<article class='box style2'>";
echo "<a href='".$baseURL.$event->profile->url.$memberid."' class='image featured' target='_blank'><img src='" . $event->profile->image->url . "' alt='' /> </a>";
echo "<h3><a href='".$baseURL.$event->profile->url.$memberid."'>" . $event->profile->name . "</a></h3>";
echo "</article>";
echo "</div>";
} else {
echo "";
}
$zaehler = $zaehler + 1;
if ($zaehler == $maxAnzahl) {
break;
}
}
?>
Gives me exactly the Images and Content i was looking for. For some reason i had already the solution in the code, but it was somehow messed up.
Thank you anyways for the help and thoughts!

For this kind of tasks like query the XML structure I prefer to use XPATH.
Try like this. I hope works for you.
<?php
// Get the XML
//###################Config Start#########################
$memberid = "123456";
$maxAnzahl = 50;
$zaehler = 0;
$baseURL = "http://www.domain.tld";
//###################Config End#########################
$source = file_get_contents('http://key:keypass#www.domain.tld/news/xml');
// DOM document Creation
$doc = new DOMDocument;
$doc->loadXML($source);
// DOM XPath Creation
$xpath = new DOMXPath($doc);
// Get all NEW events ONLY
$events = $xpath->query('//result/event[text()="NEW"]');
// Count number of events
printf('There is %d events<br />', $events->length);
// List all events
for($i = 0; $i < ($events->length); $i++) {
$event = $events->item($i);
}
?>

Would be someone able to tell me how i could specify now in that skript how to SKIP all OLD ?
You can introduce a condition right at the beginning of your foreach-loop that checks if the actual $event entry is to be skipped (filtered-out) and if so, skip to the next entry in loop:
foreach ($events->event as $event) {
$skip = $event->type != 'NEW';
if ($skip) {
continue;
}
...
Please see continue (and its sister break) to control loop structures in PHP.

Related

A way Limit data based upon unique ID

I have a xml file with a listing of trains and each train make up is tied to a specific trainID. I wrote a php script to compile this data into a user readable format but can't figure out a way to set it up to read and report only the data that is associated with the trainID. Im looking to link to the train report page with a url using the train ID. I tried making a function but I don't think that is what i need, as it was not working. Below is a portion of my XML file and list generator.
<ScnLoader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<trainList>
<TrainLoader>
<trainID>99991</trainID>
<TrainWasAI>false</TrainWasAI>
<DispatchTrainDirection>0</DispatchTrainDirection>
<ManuallyAppliedSpeedLimitMPH>2147483647</ManuallyAppliedSpeedLimitMPH>
<PreviousSignalInstruction>Clear</PreviousSignalInstruction>
<unitLoaderList>
<RailVehicleStateClass>
<rvXMLfilename>R8_CoveredHopper_PS4750_DGHX01.xml</rvXMLfilename>
<unitType>US_Freightcar</unitType>
<currentRoutePrefix>
<int>320</int>
<int>320</int>
</currentRoutePrefix>
<currentTrackSectionIndex>
<int>1365</int>
<int>1365</int>
</currentTrackSectionIndex>
<startNodeIndex>
<int>0</int>
<int>0</int>
</startNodeIndex>
<distanceTravelledInMeters>
<float>76.0736</float>
<float>90.00746</float>
</distanceTravelledInMeters>
<reverseDirection>
<boolean>true</boolean>
<boolean>true</boolean>
</reverseDirection>
<loadWeightUSTons>111.1</loadWeightUSTons>
<destinationTag>BAR HOU</destinationTag>
<unitNumber>571555</unitNumber>
</RailVehicleStateClass>
</unitLoaderList>
</TrainLoader>
</trainList>
</ScnLoader>
php
<?php
$railunit = simplexml_load_file('railUnitList.xml'); //database of railunits
$orders = simplexml_load_file('testdata.xml'); //Where the data comes from to form the list
?><pre><?php print_r($orders); ?></pre><?php
foreach ($orders->TrainLoader->trainID as $trainID){
$trainid = "99991";
}
foreach ($orders->xpath("RailVehicleStateClass") as $traininfo) {
$rvXMLfilename=(string)$traininfo->rvXMLfilename;
$unitType=(string)$traininfo->unitType;
$unitNumber=(int)$traininfo->unitNumber;
$destinationTag=(string)$traininfo->destinationTag;
$loadWeightUSTons=(int)$traininfo->loadWeightUSTons;
$totalUnitCount = $totalUnitCount + 1;
echo "<tr>";
echo "<td align='center'>";
echo $totalUnitCount;
echo "</td>";
echo "<td>";
foreach ($railunit->railUnit as $ru) {
if((string)$ru->rvXMLfilename == $rvXMLfilename){
$message = (string)$ru->reportingMark;
}
}
echo $message;
echo "</td>";
echo "<td>";
echo $unitNumber;
echo "</td>";
echo "<td>";
$message = "Not Found!";
foreach ($railunit->railUnit as $ru) {
if((string)$ru->rvXMLfilename == $rvXMLfilename){
$message = (string)$ru->unitType;
}
}
}
?>
You can add a condition in your XPath expression to retrieve only the node you want :
$railunit = $railunit->xpath("//TrainLoader[trainID = $trainid]")[0]; // retrieve all TrainLoader node that has a child 'trainID' with value '$trainid', then keep only the first one
// whole node
echo $railunit->asXML() ;
// access specific information
echo (string) $railunit->xpath('./ManuallyAppliedSpeedLimitMPH')[0]; // 2147483647

PHP sort not working in Chrome and Safari

I am not sure if it is the sort that isn't working or the way that I am outputting the information. But it would seem that the order that these "li" elements are being made is wrong sometimes.
The images in the folder are named something like
A-Mike-groomsman-topRight-light.jpg
B-James-groomsman-topRight-light.jpg
C-Jared-groomsman-topRight-light.jpg
Code is below. The "li" are in the right order in Firefox, but Chrome and Safari sometimes they put the last one first. Then sometimes they don't. Though I wonder if it could be the bxslider moving things around after the page load? Anyone experience this before?
<?PHP
$titleName = 'who\'s who'; //Wording for title of this section. Change this if you want to change the title text of this section
include 'modules/title.php';
$boydirectory = $_SERVER['DOCUMENT_ROOT']."/resources/images/who/boys";
$girldirectory = $_SERVER['DOCUMENT_ROOT']."/resources/images/who/girls";
$boy_results_array = array();
$girl_results_array = array();
if (is_dir($boydirectory))
{
if ($handle = opendir($boydirectory))
{
foreach(glob($boydirectory.'/*.*') as $file)
{
$boy_results_array[] = basename($file);
}
closedir($handle);
}
}
if (is_dir($girldirectory))
{
if ($handle = opendir($girldirectory))
{
foreach(glob($girldirectory.'/*.*') as $file)
{
$girl_results_array[] = basename($file);
}
closedir($handle);
}
}
sort($boy_results_array);
sort($girl_results_array);
?>
<div class="whoSlider boy">
<h3>Boys</h3>
<ul class="whoBoysbxslider">
<?php
if(count($boy_results_array) > 0){
for ($i = 0; $i < count($boy_results_array); $i++) {
$result = explode('-', $boy_results_array[$i]);
$name = str_replace("_", " ", $result[1]);
$job = str_replace("_", " ", $result[2]);
$alignment = $result[3];
$color = str_replace(".jpg", "", $result[4]);
echo "<li>";
echo "<img src=\"../resources/images/who/boys/$boy_results_array[$i]\" />";
echo "<div class=\"captionContainer $alignment $color\">";
echo "<span>$name</span>";
echo "<span>$job</span>";
echo "</div></li>";
}
}
?>
</ul>
</div>
<div class="whoSlider girl">
<h3>Girls</h3>
<ul class="whoGirlsbxslider">
<?php
if(count($girl_results_array) > 0){
for ($j = 0; $j < count($girl_results_array); $j++) {
$result = explode('-', $girl_results_array[$j]);
$name = str_replace("_", " ", $result[1]);
$job = str_replace("_", " ", $result[2]);
$alignment = $result[3];
$color = str_replace(".jpg", "", $result[4]);
echo "<li>";
echo "<img src=\"../resources/images/who/girls/$girl_results_array[$j]\" />";
echo "<div class=\"captionContainer $alignment $color\">";
echo "<span>$name</span>";
echo "<span>$job</span>";
echo "</div></li>";
}
}
?>
</ul>
</div>
Apparently the issue was not with php but with the BX slider. The issue is it was going to the clone slide instead of the first slide. Only in chrome and Safari. The below link talks about the issue.
https://github.com/stevenwanderski/bxslider-4/issues/154
The solution in there that worked for me was adding this to the jquery.bxslider.css file
.bx-viewport li { min-height: 1px; min-width: 1px; }
try
flush()
after echo() to make sure the content you want to print is sent to the client at that point.
First of all, PHP is a server side language and the behaviour is not effected by the browser.
So I would say that your issue is caused by bxslider which is a jQuery plugin so the behaviour it could be affected by the browser.
To check that you can press ctrl+u in firefox and chrome and see that the html is the same.

conditioning in XML parsing - PHP

Its been a while since the last time I was coding, and I am a little rusty. I am trying to parse an xml file and having a problem with the condition. Spent hours trying to figure out where is the problem, but without success...
PHP CODE:
<div id="gallery">
<?php
$cat_img="images/cat.png";
$logo_path="logos/";
$file = simplexml_load_file('stores.xml');
$old_cat="";
foreach($file->store as $store){
if($store->cat != $old_cat){
echo "<img id='cat' src='".$cat_img."'><div id='cat_text'>".$store->cat."</div><br>";
$old_cat=$store->cat;
}
echo "<div id='store'><img id='store_img' src='".$logo_path.$store->logo."' alt='logo'><br>";
echo "<store_name>".$store->name."</store_name>";
echo "<phone>".$store->phone."</phone><phone>טל: </phone></div>";
}
?>
</div>
STORES.XML
<?xml version="1.0" encoding="UTF-8"?>
<stores>
<store><logo>renuar.jpg</logo>
<name>renuar</name>
<phone>052-6059962</phone>
<cat>clothing</cat></store>
<store><logo>yoop.jpg</logo>
<name>YOOP</name>
<phone>08-6601451</phone>
<cat>clothing</cat></store>
....
</stores>
The idea is to print every store, when category changes it should print the category divider and keep printing the stores. Somehow the condition is always true and I have no idea why...
p.s
If anyone has a better idea on how to divide the categories, a different method, I would be happy to hear.
Thanks!!!
$store->cat will be SimpleXMLElement object and two object will not be same even with same category name. You need to cast it to string for comparison
Like (string) $store->cat, try this:
<?php
$cat_img = "images/cat.png";
$logo_path = "logos/";
$file = simplexml_load_file('test.xml');
$old_cat = "";
foreach ($file->store as $store) {
if ((string) $store->cat != $old_cat) {
echo "<img id='cat' src='" . $cat_img . "'><div id='cat_text'>category: " . $store->cat . "</div><br>";
$old_cat = (string) $store->cat;
}
echo "<div id='store'><img id='store_img' src='" . $logo_path . $store->logo . "' alt='logo'><br>";
echo "<store_name>" . $store->name . "</store_name>";
echo "<phone>" . $store->phone . "</phone><phone>טל: </phone></div>";
}
?>

Separate MySQL results into Divs using while loop

Just beginning PHP to bear with me.
Results I'm trying to achiever:
I have a table of YouTube URL's and MetaData.
Trying to build this:
<div class="slide">
<iframe></iframe>
<iframe></iframe>
</div>
<div class="slide">
<iframe></iframe>
<iframe></iframe>
</div>
Two videos per slide, then I'm going to paginate through results using Deck.js.
I suspect I'm going about this completely the wrong way, not that experienced at programmin g logic;
while($data = mysql_fetch_array($result)) {
for ($counter = 1; $counter<=2; $counter++) {
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
/* If Video 1, increment counter for 2nd video */
if ($counter == 1) {
$counter++;
}
/* If Video 2, close div and reset counter */
else if ($counter == 2) {
echo "</div>";
$counter = 1;
}
/* If error break out */
else {
echo "</div>";
break;
}
}
}
Basically trying to nest loops to keep track of how many videos per div and start a new one when a div has two.
I've tried a few different ways, this being the latest. Results in:
<div class="slide">
<iframe></iframe>
<div class="slide>
<iframe></iframe>
Hit the blank wall now, not sure what to try next. Willing to use/learn any method to accomplish the results, just not sure where to go at this point.
Cheers.
You could remove the second loop all together using the % operator (modulus). The idea is that a % b === 0 then the number a was evenly divisible by b. Using this, you can easily check for even or odd or every Nth row.
$k = 1;
echo "<div class=\"slide\">";
while($data = mysql_fetch_array($result)) { // you should really change to mysqli or PDO
if($k % 3 === 0){
echo "</div>";
echo "<div class=\"slide\">";
}
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
$k++;
}
echo "</div>";
Put the echo <div> before the for loop (still inside the while loop) and the </div> after the for loop
In your while loop you're retrieving just one row, but then you're iterating over it twice with a nested loop. Do away with the inner loop and just use a flip-flop variable to track left and right. I think this will do what you want:
$left=true; // track whether we're emitting HTML for left or right video
while($data = mysql_fetch_array($result)) {
if ($left) {
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
}
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
if (!$left) {
echo "</div>";
}
$left = !$left; // invert $left to indicate we're emitting the right iFrame
}
// end of loop. If we had an odd number of
// videos, tidy up the HTML
if (!$left) {
echo "</div>";
}
PHPFiddle
<?php
$x = 10;
$counter = 0;
while($x > 0)
{
if($counter != 0 && $counter % 2 == 0)
{
echo "ENDOFSLIDE</br>";
}
if($counter == 0 || $counter % 2 == 0)
{
echo "SLIDE</br>";
}
echo "iframe => $x </br>";
$x--;
$counter++;
}
echo "ENDOFSLIDE";
?>
It won't work because the for loop is inside the fetch loop for the SQL data. The second iteration of the for loop does not have a new SQL row. A better solution would be to capture the common column that identifies the two videos (the title) and generate a new div whenever that value changes. Try something like this, which will work for any number of SQL rows with the same title. This will also give proper results if the SQL query returns no rows and will handle the potential of a title with only one URL - which could get ugly if you merely flip-flop and end up with URLs on the wrong title. Of course, as in your current solution, your SQL query must ORDER BY VIDEO_TITLE so the rows are adjacent. I didn't run it, but should be close.
$lastTitle = "";
$n = 0; //count SQL rows processed
while($data = mysql_fetch_array($result)) {
// See if the title changed from last
if( $data['VIDEO_TITLE'] != $lastTitle ) {
// if we processed any rows, must end the current div before starting a new one
if( $n > 0 )
echo "</div>";
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
//save the title as last title
$lastTitle = $data['VIDEO_TITLE'];
}
$n++; //count the SQL row
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
}
if( $n > 0 )
echo "</div>";

Searching Multiple Elements In XML File

I'm using the W3C Live Ajax Search found here. Their code only searches one element, the "title". I would like to have it take the user's query and search through multiple elements, for example, the 'title' and the 'url'.
<?php
$xmlDoc=new DOMDocument();
$xmlDoc->load("live.xml");
$x=$xmlDoc->getElementsByTagName('link');
//get the q parameter from URL
$q=$_GET["q"];
//lookup all links from the xml file if length of q>0
if (strlen($q)>0)
{
$hint="";
for($i=0; $i<($x->length); $i++)
{
$d=$x->item($i)->getElementsByTagName('title');
$z=$x->item($i)->getElementsByTagName('url');
if ($d->item(0)->nodeType==1)
{
//find a link matching the search text
if (stristr($d->item(0)->childNodes->item(0)->nodeValue,$q) !=false)
{
if ($hint=="")
{
$hint=
$z->item(0)->childNodes->item(0)->nodeValue . "<br />" .
$d->item(0)->childNodes->item(0)->nodeValue;
}
else
{
$hint=$hint . "<br /><br />" .
$z->item(0)->childNodes->item(0)->nodeValue . "<br />" .
$d->item(0)->childNodes->item(0)->nodeValue;
}
}
}
}
}
// Set output to "no suggestion" if no hint were found
// or to the correct values
if ($hint=="")
{
$response="no suggestion";
}
else
{
$response=$hint;
}
//output the response
echo $response;
?>
Can somebody give me an example of how to make it work? From what I understand, stristr will only search one haystack and you can't use arrays, so is there another way? Thanks in advance!
Well, I figured out a way:
if ( (stristr($d->item(0)->childNodes->item(0)->nodeValue,$q) !=false) ||
(stristr($z->item(0)->childNodes->item(0)->nodeValue,$q) !=false) )
I doubt this is the optimal way, so if anybody has a better solution feel free to add it.

Categories