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
Related
I'm a beginner in PHP and working on an API project which has to get results from a server I connected via API.
I am getting the results, but I would like to have them well arranged in a simple table.
This is what I am getting:
I used the following code:
$api = new SplynxAPI($api_url, $key, $secret);
$locationsApiUrl = "admin/administration/locations";
echo "<pre>";
echo "List locations\n";
$result = $api->api_call_get($locationsApiUrl);
echo "Result: ";
if ($result) {
echo "Ok!\n";
print_r($api->response);
} else {
echo "Fail! Error code: $api->response_code\n";
print_r($api->response);
}
echo "\n-------------------------------------------------\n";
Kindly assist me on this one.
The following code will render your response in a HTML <table>.
$api = new SplynxAPI($api_url, $key, $secret);
$locationsApiUrl = "admin/administration/locations";
$result = $api->api_call_get($locationsApiUrl);
if ($result) {
echo "<table>";
foreach($api->response as $row){
echo sprintf('<tr><td>%s</td><td>%s</td></tr>', $row['id'], $row['name']);
}
echo '</table>';
} else {
echo "Fail! Error code: $api->response_code\n";
print_r($api->response);
}
echo "\n-------------------------------------------------\n";
You are directly getting the response "$api->response" as an array. So simply use a loop and populate it in table as you like.
Ex:
foreach($api->response as $apiData) {
// Your code
}
how can i pass the id as the name.I used this code.
<?php
$i = 1;
foreach ($view as $row)
{
echo "<tr>";
echo "<td>".$i."</td>";
echo "<a href="<?php echo base_url();?>admin/play/songs/<?php echo $row->audio"><td>". $row->audio . "</td>";
$i++;
echo "</tr>";
}
?>
I want to play the song when user press the name of the song.but i am not able to pass the name of the song to my controller "play".so please help and this is my controller where i want to pass the data.
class Play extends CI_Controller {
public function songs($name){
$data['name'] = $name;
$this->load->view('admin/play',$data);
}
You should grab id instead of name it will make your job easier.
<?php
$i = 1;
foreach ($view as $row)
{
echo "<tr>";
echo "<td>".$i."</td>";
echo "<a href="<?php echo base_url();?>admin/play/songs/<?php echo $row->id"><td>". $row->audio . "</td>";
$i++;
echo "</tr>";
}
?>
First of all you should know that you can pass the url you want after base_url as a parament in base_url like
base_url('admin/play/songs/');
Secondly you can pass anything to controller via this method
base_url('admin/play/songs/{$row->audio}');
Just excited to know if it works
I am trying to extract multiple values from a row in a table in a mysql database. I want the selector to show the description only, and after the form is submitted, I want to be able to access additional information from that row. I am able to get all of the item_types out into an array, but I am not sure how to add the item_id. I don't want item_id to show up in the html selector.
I tried a few things like array_push. The only way I can think of getting this done is by making one big string in "value" and extracting the parts after the form is submitted.
Here is the function so far:
function createDropdown() {
echo '<select multiple name="items[]">';
try {
$items = mysql_query("SELECT item_id,item_type FROM items");
while ($row = mysql_fetch_assoc($items)) {
echo '<option value="'.$row['item_type'].'"';
echo '>'. $row['item_type'] . '</option>'."\n";
}
}
catch(PDOException $e) {
echo 'No results';
}
echo '</select>';
}
Hmm you can try to generate a lookup table whenever you create a drop-down list:
function createDropdown(&$ddlLookup) {
echo '<select multiple name="items[]">';
try {
$items = mysql_query("SELECT item_id,item_type FROM items");
while ($row = mysql_fetch_assoc($items)) {
echo '<option value="'.$row['item_type'].'"';
echo '>'. $row['item_type'] . '</option>'."\n";
$ddlLookup[$item_type] = $item_id;
}
}
catch(PDOException $e) {
echo 'No results';
}
echo '</select>';
}
Then whenever you need the id for a given description you use that table(array) to get it:
$mainDropdownLUT = array();
createDropdown($mainDropdownLUT);
var_dump($mainDropdownLUT['testCow']);
-> 734
Also, if you need to pass it to another page it can be serialized and added to a hidden field.
$mainDropdownLUT = serialize($mainDropdownLUT);
"<input type="hidden" value =\"$mainDropdownLUT\">"
-------------------------**OTHER PAGE **--------------
$mainDropdownLUT = unserialize($mainDropdownLUT);
I have successfully put together a PHP script to read content of an xml file and output the result to HTML page. The only bit I am struggling with is how to format the output into a table.
PHP Script:
<?php
// Loading the XML file
$xml = simplexml_load_file("ftpxml.xml");
echo "<h2>".$xml->getName()."</h2><br />";
foreach($xml->children() as $ftpxml)
{
echo "PID : ".$ftpxml->attributes()->pid."<br />";
echo "Account : ".$ftpxml->attributes()->account." <br />";
echo "Time : ".$ftpxml->attributes()->time." <br />";
echo "<hr/>";
}
?>
HTML Result:
PID : 279
Account : account001
Time : 137
----------------------------------------------------------------
PID : 268
Account : account002
Time : 301
----------------------------------------------------------------
PID : 251
Account : account003
Time : 5
----------------------------------------------------------------
I am lost as to how to display each table headings and the corresponding contents. I am new to PHP so please guide me or if already answered else where, please provide link so I can learn from it.
Thanks
<?php
// Loading the XML file
$xml = simplexml_load_file("ftpxml.xml");
echo "<h2>".$xml->getName()."</h2><br />";
echo "<table>";
foreach($xml->children() as $ftpxml)
{
echo "<tr><td>PID : ".$ftpxml->attributes()->pid."</td></tr>";
echo "<tr><td>Account : ".$ftpxml->attributes()->account." </td></tr>";
echo "<tr><td>Time : ".$ftpxml->attributes()->time." </td></tr>";
}
echo "</table>";
?>
echo '<table>';
echo '<thead><tr><th>PID</th><th>Account</th><th>Time</th></tr></thead><tbody>';
foreach($xml->children() as $ftpxml)
{
echo '<tr>';
echo "<td>PID : ".$ftpxml->attributes()->pid."</td>";
echo "<td>Account : ".$ftpxml->attributes()->account."</td>";
echo "<td>Time : ".$ftpxml->attributes()->time." </td>";
echo '</tr>';
}
echo '</tbody></table>';
I assume you want to make the different values different fields in the table:
// Loading the XML file
$xml = simplexml_load_file("ftpxml.xml");
echo "<h2>".$xml->getName()."</h2><br />";
echo "<table><thead><tr><th>PID</th><th>Account</th><th>Time</th></tr></thead><tbody>";
foreach($xml->children() as $ftpxml)
{
echo '<tr>';
echo '<td>' . $ftpxml->attributes()->pid . "</td>";
echo '<td>' . $ftpxml->attributes()->account . "</td>";
echo '<td>' . $ftpxml->attributes()->time . "</td>";
echo '</tr>';
}
echo '</tbody></table>';
is there a way to speed up my code? It takes about 15 seconds to load ... I don't really see a way to reduce my code... I just thought about inserting the values into database, so the user does not have to load new info every time.. but the thing is that my cron only allows 1 load per hour ... by loading new info on every load it gives me fresh information..
$q1=mysql_query("SELECT * FROM isara");
while($r1=mysql_fetch_array($q1)){
$named=$r1['name'];
$idd=$r1['id'];
$descd=$r1['desc'];
$online=check_online($named);
$char = new Character($r1['name'],$r1['id'],$r1['desc']);
if($online == "online"){
$char->rank = $i++;
}
else{
$char->rank = 0;
}
$arr[] = $char;
}
?>
<br />
<h2 style="color:green">Online enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank>=1){
echo "<a style=\"color:green\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
<br />
<h2 style="color:red">Offline enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank==0){
echo "<a style=\"color:red\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
As I wrote in the comment, fetch the page once instead of once for every name in the database.
Pseudo code for my comment:
users = <get users from database>
webpage = <get webpage contents>
for (user in users)
<check if user exists in webpage>
As mentioned in the comments you're calling a webpage for each entry in your database, assuming that's about 2 seconds per call it's going to slow you down a lot.
Why don't you call the page once and pass the contents of it into the check_online() function as a parameter so your code would look something like this which will speed it up by quite a few magnitudes:
$content=file_get_contents("http://www.tibia.com/community/?subtopic=worlds&world=Isara",0);
$q1=mysql_query("SELECT * FROM isara");
while($r1=mysql_fetch_array($q1)){
$named=$r1['name'];
$idd=$r1['id'];
$descd=$r1['desc'];
$online=check_online($named,$content);
$char = new Character($r1['name'],$r1['id'],$r1['desc']);
if($online == "online"){
$char->rank = $i++;
}
else{
$char->rank = 0;
}
$arr[] = $char;
}
?>
<br />
<h2 style="color:green">Online enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank>=1){
echo "<a style=\"color:green\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
<br />
<h2 style="color:red">Offline enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank==0){
echo "<a style=\"color:red\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
and your check_online() function would look something like this:
function check_online($name,$content){
$count=substr_count($name, " ");
if($count > 0){ $ex=explode(" ",$name); $namez=$ex[1]; $nameused=$namez; }
else{ $nameused=$name; }
if(preg_match("/$nameused/",$content)){ $status="online"; }
else{ $status="offline"; }
return $status;
}
You can also do the following to make it faster
Stop using select * which is very bad on innodb
Put better indexes on your database to make the recordset return faster
Install PHP 5.4 as it's faster especially as you're creating a new object in each iteration
Use a byte code accelerator/cache such as xdebug
you should avoid using distinct (*) keyword in your SQL Query
for more information read this http://blog.sqlauthority.com/category/sql-coding-standards/page/2/