Parse XML with PHP where Value equals XX - php

Want to set up a page that parse out info from a XML feed according to a give ID...
Like "Show the Course->info where Course->ID = 123"
Probably "need" to get the id from a URL Variable ... urL: ://.../courseinfo.php?id=123
This show each instance - but I want a solution that shows only info from One particual ID.
"simialr" to a sql query like "GET * where COURSE_ID=" & $urlcourseid"
$xml=simplexml_load_file("https://www.kursadmin.org/pls/kas/sf_fu.create_web_cdata_xml");
foreach($xml as $x) {
foreach($x->KURS as $y){
echo "Kursnavn: " . $y->KURS_NAVN . "<br>";
echo "KursID: " . $y->KURS_ID . "<br><br>";
echo "Formål: " . $y->FORMAL . "<br>";
//echo "Beskrivelse: <p>" . $y->INNHOLD . "</p>";
echo "<br><br> <Hr>";
}
}
Any suggestions?

As everyone's probably suggested, you should be using XPath to query this. What they're leaving out is that you have to mind the XML namespace before you can do that here. Here's a programmatic way to both mind the namespace, and to query for a specific record ID:
$xml = simplexml_load_file( "sf_fu.create_web_cdata_xml" );
$namespaces = $xml->getNamespaces( true ); # array([]="crystal-reports:schemas")
$namespace = array_shift( $namespaces ); # urn:crystal-reports:schemas
$xml->registerXPathNamespace("kurses", $namespace );
$results = $xml->xpath( "//kurses:KURS[kurses:KURS_ID=1463486771]" );
Note that my XPath query is prefixed with kurses: - that is the namespace prefix that I designated I wanted to use with the queries, that the XML file reflects (see the Report xmlns='' tag)
Anyhow, the result is an array of records, in our case length 1 since there's only one ID with that number. Printing it out looks like what you'd expect (redacted a few details):
print_r($results) = Array (
[0] => SimpleXMLElement Object (
[#attributes] => Array (
[SectionNumber] => 0
[teller] => 0
)
[KURSSERIE_ID] => SimpleXMLElement Object (
[#attributes] => Array (
[FieldName] => {ARRMENT_TBL.AM_ID}
)
)
[KURS_ID] => 1463486771
[KURS_NAVN] => Norsk litt øvet (A2) - Eid
[KLSTART] => 1730
Given that the record ID # is an integer, you should be able to cheaply sanitize it by doing something like:
$KURS_ID = intval( $_GET['KURS_ID'] );
...
$results = $xml->xpath( "//kurses:KURS[kurses:KURS_ID={$KURS_ID}]" );

the obvious way:
foreach($xml as $x) {
foreach($x->KURS as $y){
if( $y->KURS_ID == $_GET['id']){
echo "Kursnavn: " . $y->KURS_NAVN . "<br>";
echo "KursID: " . $y->KURS_ID . "<br><br>";
echo "Formål: " . $y->FORMAL . "<br>";
//echo "Beskrivelse: <p>" . $y->INNHOLD . "</p>";
echo "<br><br> <Hr>";
}
}
}

Related

Loop through associative array and assign values

I have an array:
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
What I want is to loop through this array, which I have done, but I am now confused because I don't know how to get the output I desire.
foreach ($array as $key => $value) {
//echo $key . "\n";
foreach ($value as $sub_key => $sub_val) {
if (is_array($sub_val)) {
//echo $sub_key . " : \n";
foreach ($sub_val as $k => $v) {
echo "\t" .$k . " = " . $v . "\n";
}
} else {
echo $sub_key . " = " . $sub_val . "\n";
}
}
}
The above code loops through the array, but this line of code:
echo $sub_key . " = " . $sub_val . "\n";
gives me:
step_no = 1 description = Ensure that you have sufficient balance step_no = 2 description = Approve the request sent to your phone
when I change it to:
echo $sub_val . "\n";
it gives me:
1 Ensure that you have sufficient balance 2 Approve the request sent to your phone
But I what I truly want is:
1. Ensure that you have sufficient balance
2. Approve the request sent to your phone
Is this possible at all? Thanks.
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
foreach($instructions as $instruction) {
echo $instruction['step_no'] . '. ' . $instruction['description'] . "\n";
}
If it's HTML you may want to use <ol> and <li>.
It smells like you are not running this script in command line but in browser. If so, then \n makes no visual effect (unless within <pre> block) and you u must use HTML tag <br /> instead. Also, drop concatenation madness and use variable substitution:
echo "{$sub_key}. = {$sub_val}<br/>";
You can simple achieve this way
<?php
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
foreach($instructions as $instruction){
echo $instruction['step_no'].'. '.$instruction['description'].PHP_EOL;
}
?>
Alway keep it simple.

Handling Query Results - Quickbooks API PHP

I am new to the Quickbooks API and am having some trouble doing something with the data I pull from a query. I am wanting to make a list of Vendor names. Normally I would use a while loop pulling from an SQL DB, however, I am not even able to print one result. I am sure it is something basic, however, I am not familiar with OOP queries and it seems that is similar to how Quickbooks runs their queries. I am able to connect and print an array with the below info.
Note: I just did MAXRESULTS 1 so that I could get it down to just displaying the DisplayName property.
// Run a query
$entities = $dataService->Query("Select * from Vendor MAXRESULTS 1");
$error = $dataService->getLastError();
if ($error) {
echo "The Status code is: " . $error->getHttpStatusCode() . "\n";
echo "The Helper message is: " . $error->getOAuthHelperError() . "\n";
echo "The Response message is: " . $error->getResponseBody() . "\n";
exit();
}
print "<pre>";
print_r($entities);
print "</pre>";
With that I get the result of this:
Array
(
[0] => QuickBooksOnline\API\Data\IPPVendor Object
(
[IntuitId] =>
[Organization] =>
[Title] =>
[GivenName] =>
[MiddleName] =>
[FamilyName] =>
[Suffix] =>
[FullyQualifiedName] =>
[CompanyName] =>
[DisplayName] => Bob's Burger Joint
[PrintOnCheckName] => Bob's Burger Joint
[UserId] =>
[Active] => true
)
)
I have tried with no luck these:
echo "Test 1: " . $entities->DisplayName;
echo "Test 2: " . $entities[0]['DisplayName'];
echo "Test 3: " . $entities[0][DisplayName];
echo "Test 4: " . $entities->0->DisplayName;
/*Start Test 5*/
$sql = 'Select * from Vendor MAXRESULTS 1';
foreach ($dataService->Query($sql) as $row) {
print $row['DisplayName'] . "\t";
print $row['PrintOnCheckName'] . "\t";
print $row['Active'] . "\n";
}
/*End Test 5*/
First, how do I print just the DisplayName property?
Second, how would I do a loop via the OOP method to make a table of all Vendor names?
You can't access properties of an object with [''] unless IPPVendor class implements ArrayAccess.
To access the properties while looping, you will need to use the -> syntax like below:
$sql = 'Select * from Vendor MAXRESULTS 1';
foreach ($dataService->Query($sql) as $row) {
echo $row->DisplayName . "\t";
echo $row->PrintOnCheckName . "\t";
echo $row->Active . "\n";
echo PHP_EOL; // to end the current line
}
To display these details in a HTML table, you can make use of heredoc syntax while looping to make your code look clean.
$sql = 'Select * from Vendor MAXRESULTS 1';
$html = <<<html
<table border='1'>
<thead>
<tr>
<th>DIsplayName</th>
<th>PrintOnCheckName</th>
<th>Active</th>
</tr>
</thead>
<tbody>
html;
foreach($dataService->Query($sql) as $row) {
$html .= <<<html
<tr>
<td>$row->DisplayName</td>
<td>$row->PrintOnCheckName</td>
<td>$row->Active</td>
</tr>
html;
}
$html .= <<<html
</tbody>
</table>
html;
echo $html;

Nested foreach when reading XML (in PHP)

I need to create a CRON job that are weekly going to read a XML file. The XML file contains information about all the shows at a range of cinemas.
What I want to do is to read the XML file, extract the information I need about each show, and then upload each show to a database. But I run into trouble when I start nesting the for-loops.
I want each tuple to contain the following information:
Tile | FilmWebNr | Rating | Version | Center | Screen | Date | Time |
The URL for the XML is http://217.144.251.113/static/Shows_FilmWeb.php
Here is a pastebin where I try to list all the dates for each screen per Title.
Here is the result. As you can see, the dates is only displayed when there are more than 1 screen per Title. I dont get why the attributes array isn't always available.
I struggle with getting the last three (screen, date and time).
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$array = (array) simplexml_load_string($response_xml_data);
$json = json_encode($array);
$configData = json_decode($json, true);
$movies = $configData['Performances']['Title'];
foreach ($movies as $title) {
echo "Title: " . $title['#attributes']['Name'] . '<br/>';
echo "FilmWebNr: " . $title['FilmWebNum'] . '<br/>';
echo "Rating: " . $title['TitleRating'] . '<br/>';
echo "Version: " . $title['TitleVersion'] . '<br/>';
echo "Center: " . $title['Center']['#attributes']['Name'] . '<br/>';
foreach ($title['Center']['Screen'] as $screen) {
//here I run into trouble
}
}
Let say I try to add the following in the inner loop:
$screen['#attributes']['Name'];
I get an error saying "Undefined index: #attributes".
So sometimes the attributes seems to be in an array, but sometimes not. Even though It is always a part of the XML.
Rather than going from XML-JSON-Arrays, it may be better to learn how to work with SimpleXML and you will find it's quite easy.
The main thing is to get used to how the various elements are layered and use foreach loops to iterate over the blocks...
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$movies = $data->Performances->Title;
foreach ($movies as $title) {
echo "Title: " . $title['Name'] . '<br/>';
echo "FilmWebNr: " . $title->FilmWebNum . '<br/>';
echo "Rating: " . $title->TitleRating . '<br/>';
echo "Version: " . $title->TitleVersion . '<br/>';
echo "Center: " . $title->Center['Name'] . '<br/>';
foreach ($title->Center->Screen as $screen) {
echo "screen:".$screen['Name']. '<br/>';
foreach ( $screen->Date as $date ) {
echo "Date:".$date['Name']. '<br/>';
foreach ( $date->ShowID as $showID ) {
echo "Time:".$showID->Time. '<br/>';
}
}
}
}

Search multi-dimensional array and return the parent key

I have a multi-dimensional array $games_array that looks like this:
<?php
$games_array = array(
"game-one" => array(
"name" => "Game One",
"download_id" => "gameone",
"file" => "./games/files/Game One.zip"
),
"game-two" => array(
"name" => "Game Two",
"download_id" => "gametwo",
"file" => "./games/files/Game Two.zip"
)
);
?>
For example, to access the first game's name, I'd use $games_array["game-one"]["name"] which works fine.
Okay, now to the problem: I have a value, for example gameone, that corresponds to download_id (which is a key that every game in $games_array has).
Now I want to find out the key, in this example game-one or game-two, of the array that contains this value for the key download_id. That works.
What I do in the code below is iterate over $games_array and search each game for the value (in the code below gameone). If it's found, the key for that value is returned.
The next thing I do (if ($key_found) { ...) is to try and find out the key file's value by using the array in which the value for which I originally searched was found, and save it in $file.
Unfortunately $file is always empty and I don't know why.
<?php
$key = "";
$key_found = false;
$search_for_value = "gameone"; // search for game's download id in array
$file = "";
foreach($games_array as $game_id => $game_data) {
$key = array_search($search_for_value, $game_data);
echo "Searching for value <b>" . $search_for_value . "</b> in sub-array <b>" . $game_id . "</b>...<br />";
if ($key === FALSE) {
echo "Search returned FALSE<br /><br />";
} else if ($key === NULL) {
echo "Search returned NULL<br /><br />";
} else {
echo "\$key <b>" . $key . "</b> found! <br /><br />";
$key_found = true;
}
if ($key_found) {
// Key "download_id" found. Now search the parent array for the found key and use the
// returned result as the new key to access the "file" value in the found game's id in $games_array
$file = $games_array[array_search($key, $game_id)]["file"];
echo "The key <b>" . $key . "</b> was found.<br/>";
echo "\$file = " . $file . "<br />";
echo "Exiting loop.<br /><br />";
break;
}
}
$file = $games_array[$games_data]["file"];
echo "Checking if the file \"" . $file . "\" exists...<br />";
echo (file_exists($file) ? "File \"" . $file . "\" exists." : "File \"" . $file . "\" does not exist.");
?>
I hope you understand my problem and can help me. I'd appreciate it very much... I'm really stuck here.
If you already know that you'll be searching in download_id, then you are making this code far more complicated than it needs to be. I'm not sure if there's a real answer to your question other than trying a completely different approach.
Instead of using all these array_search calls, you can directly check the value of the column you know you're looking for, like this:
foreach( $games_array as $game_id => $game_data ) {
if( $game_data["download_id"] == $search_for_value ) {
$file = $game_data["file"];
break;
}
}

Get values from PHP array

I created a foreach loop in PHP like this:
foreach( $value as $element_content => $content ) {
$canvas_elements = "<div id='" . $element_id . "'>" . $content . "</div>";
$elements[] = $canvas_elements;
}
So I get the values in a PHP array like this:
print_r($elements);
But this gives the results:
Array ( [0] =>
Text to edit
[1] =>
Text to edit
)
But I only want this output and not Array ( [0] => etc:
<div id="element_id1"></div>
<div id="element_id2"></div>
How is this done?
Why bother with the array, if you want nothing but echo/print out some markup:
foreach( $value as $element_content => $content )
{
echo "<div id='" . $element_id . "'>" . $content . "</div>";
}
Whill do, however, if you insist on using that array:
echo implode('', $elements);
turns the array into a string, just like you wanted it to. Your using print_r is not the way forward, as it's more of a debug function: check the docs
Prints human-readable information about a variable
Just a little detail: you don't seem to be declaring $elements as an array anywhere. PHP will create a new variable, and assign it an empty array for you, true enough, but if you change your ini settings to E_STRICT | E_ALL, you'll notice that it doesn't do this without complaining about it. (and rrightfully so)
It's always better to declare and initialize your variables beforehand. writing $elements = array(); isn't hard, nor is it very costly. At any rate it's less costly than producing a notice.
use like this
<?php
$data = array('a'=>'apple','b'=>'banana','c'=>'orange');
$string = implode("<br/>", $data);
?>
<pre><?php print_r($string); ?></pre>
OUTPUT
apple
banana
orange
print_r($array) is a function to display the value of the variable to the user. it's created for debugging purposes. If you want to have a HTML output, please use "echo" or something particular.
foreach( $value as $element_content => $content ) {
echo "<div id='" . $element_id . "'>" . $content . "</div> \n";
}
$elements = array();
foreach( $value as $element_content => $content ) {
$canvas_elements = "<div id='" . $element_id . "'>" . $content . "</div>";
$elements[] = $canvas_elements;
}
echo $mergedStrArray = implode("\n", $elements);
Can you try for me, Does it work?

Categories