I've been looking for answers to my problem on SW but no luck so far..so here it goes.
I'm writing a form where the user can search for items that are written in a xml file on the server...the search function works pretty well; the form sends the values to a php file and using simplexml it retrieves the data from the xml file using a foreach with an if/else statement. However, when there is no item found on the xml file, that's where the issue comes.
Here's my php:
<?php
$zip = $_POST['zip'];
$id = $_POST['id'];
$xml = simplexml_load_file("lista.xml");
foreach ($xml as $entry){
if (($entry->zipCode == $zip) && ($entry->id == $id)){
?>
<p>Id: <?php echo $entry->id;?></p>
<p>Zip: <?php echo $entry->zipCode;?></p>
<p>Item: <?php echo $entry->item;?></p>
<?php
}
else {echo 'nothing found';}
}?>
And this is my xml:
<?xml version="1.0" encoding="utf-8"?>
<entries>
<entry>
<id>id1</id>
<zipCode>zip1</zipCode>
<item>1</item>
</entry>
<entry>
<id>id2</id>
<zipCode>zip2</zipCode>
<item>2</item>
</entry>
<entry>
<id>id3</id>
<zipCode>zip3</zipCode>
<item>3</item>
</entry>
</entries>
The issue is that instead of showing 'nothing found' just once if there is no item within the whole xml file, it shows 'nothing found' in every entry that does not have the search query on it.
So, for instance, if $zip = zip4 and $id = id4 the answer is:
nothing found
nothing found
nothing found
instead of just one 'nothing found'
What's the correct way of writing that piece of code??
Thanks everyone in advance!!!
Use a variable to keep track of whether you found anything.
$found = false;
foreach ($xml as $entry){
if (($entry->zipCode == $zip) && ($entry->id == $id)){
$found = true;
?>
<p>Id: <?php echo $entry->id;?></p>
<p>Zip: <?php echo $entry->zipCode;?></p>
<p>Item: <?php echo $entry->item;?></p>
<?php
}
}
if (!$found) {
echo 'nothing found';
}
Related
There's a few threads about this, but I couldn't find a solution to this issue in them. I hope it doesn't violate duplicate rules.
I've tested the following code with static XML and it works great, but said XML did not contain any headers.
I'm trying to remove headers through code after making a POST request so I can continue to process the resulting XML, but I'm not having any luck with it.
This is the XML:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><AUTOS_Cotizar_PHPResponse xmlns="http://tempuri.org/"><AUTOS_Cotizar_PHPResult><auto xmlns=""><operacion>1555843</operacion><statusSuccess>TRUE</statusSuccess><statusText></statusText><cotizacion><cobertura><codigo>A0</codigo><descripcion>RESPONSABILIDAD CIVIL SOLAMENTE</descripcion><premio>928,45</premio><cuotas>01</cuotas><impcuotas>928,45</impcuotas></cobertura></cotizacion><datos_cotiz><suma>477250</suma><uso>901</uso></datos_cotiz></auto></AUTOS_Cotizar_PHPResult></AUTOS_Cotizar_PHPResponse></soap:Body></soap:Envelope>
this is the code:
//converting raw cURL response to XML
$temp1 = htmlspecialchars ($reply);
//replacing top headers
$temp2 = str_replace('<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><AUTOS_Cotizar_PHPResponse xmlns="http://tempuri.org/"><AUTOS_Cotizar_PHPResult>', "<<<'EOD'", $temp1);
//replacing closing header tags
$temp3 = str_replace('</AUTOS_Cotizar_PHPResult></AUTOS_Cotizar_PHPResponse></soap:Body></soap:Envelope>', "EOD;", $temp2);
//this returns the original $temp1 without having anything replaced
echo $temp3;
//simplexml conversion
$xml = simplexml_load_string($temp3);
//running through the array and printing all values
if ($xml !== false) {
foreach ($xml->cotizacion as $cotizacion) {
foreach ($cotizacion->cobertura as $cobertura) {
echo $cobertura->codigo;
echo '<br>';
echo $cobertura->descripcion;
echo '<br>';
echo $cobertura->premio;
echo '<br>';
echo $cobertura->cuotas;
echo '<br>';
echo $cobertura->impcuotas;
echo '<br>';
}
}
}
There are probably more efficient ways to do this, or maybe I'm not doing this correctly. I'm just about learning right now, so feel free to correct me in any way if you want, I'd appreciate it!
The way you are processing the response string is a bad idea, you should stick to processing the content as XML and work with it. This uses XPath to find a start point to process the data (which I can't test with the current sample), but should help with what you need to do...
// Load the original reply
$xml = simplexml_load_string($reply);
//running through the array and printing all values
if ($xml !== false) {
// Find the <auto> element (use [0] as you want the first one)
$auto = $xml->xpath("//auto")[0];
// Loop through the cotizacion elements in the auto element
foreach ($auto->cotizacion as $cotizacion) {
foreach ($cotizacion->cobertura as $cobertura) {
echo $cobertura->codigo;
echo '<br>';
echo $cobertura->descripcion;
echo '<br>';
echo $cobertura->premio;
echo '<br>';
echo $cobertura->cuotas;
echo '<br>';
echo $cobertura->impcuotas;
echo '<br>';
}
}
}
The SOAP response is still an XML document, so work with it instead of fighting it. Treating it as a string is definitely not great.
As far as I can tell you're trying to work with all the <cotizaction> elements. It's simple to find elements inside an XML document. Read up on XPath.
$xml = simplexml_load_string(htmlspecialchars($reply));
if ($xml) {
foreach ($xml->xpath('//cotizacion') as $cotizacion) {
// do your thing
}
}
I have an XML file with this structure:
<markers>
<marker>
<marker_id>...</marker_id>
<map_id>...</map_id>
<title>Test Location 1</title>
<address>Blah Blah Blah</address>
<desc/>
<pic/>
<icon>...</icon>
<linkd/>
<lat>...</lat>
<lng>...</lng>
<anim>...</anim>
<category>...</category>
<infoopen>...</infoopen>
</marker>
</markers>
Basically it's pulling data from a Google Maps location XML file.
I need to echo the bit only
Here's what I have so far:
<?php
$url = 'myurl/1markers.xml';
$file = file_get_contents($url);
$xml = simplexml_load_string($file);
foreach($xml->markers as $x) {
$location = $x->marker->title;
echo $location;
}
?>
It doesn't seem to be echoing...?
I've probably not done it right somewhere in the foreach, can anybody see what I'm missing?
Thanks
Mark
Use simplexml_load_file()
<?php
$xml = simplexml_load_file("new.xml");
foreach($xml as $x) {
$location = $x->title;
echo $location;
}
?>
markers is a root tag. Refering to http://php.net/manual/en/simplexml.examples-basic.php, your code should look like:
foreach($xml->marker as $x) {
echo $x->title;
}
Could be useful to replace the file_get_contents: http://www.php.net/manual/en/function.simplexml-load-file.php
<?php
$XML = <<<'XML'
<markers>
<marker>
<marker_id>...</marker_id>
<map_id>...</map_id>
<title>Test Location 1</title>
<address>Blah Blah Blah</address>
<desc/>
<pic/>
<icon>...</icon>
<linkd/>
<lat>...</lat>
<lng>...</lng>
<anim>...</anim>
<category>...</category>
<infoopen>...</infoopen>
</marker>
</markers>
XML;
$xml = simplexml_load_string($XML);
//This seems to fix things, issue was that you were trying to access the root tag which is implied.
foreach($xml->marker as $x) {
$location = $x->title;
var_dump($location);
}
?>
When I try to get values it doesn't seem to work. The xml file contains multiples of the same node <post> and I thought you could call a specific node like an array, but that doesn't seem to work. Below I have included the code.
File that gets xml values:
<?php
if(file_exists('settings.xml')){
$settings = simplexml_load_file('settings.xml');
$site_title = $settings->title;
$site_name = $settings->title;
$site_stylesheet = "css/main.css";
$theme_folder = "themes/".$settings->theme;
if(file_exists('posts.xml')){
$posts = simplexml_load_file('posts.xml');
$post = $posts->post[$_GET['post']];
$post_title = $post->title;
$post_content = $post->content;
$post_author = $post->author;
include($theme_folder."/header.php");
include($theme_folder."/post.php");
include($theme_folder."/footer.php");
} else {
exit("File \"posts.xml\" does not exist!");
}
} else {
exit("File \"settings.xml\" does not exist!");
}
?>
File that is included in the file above and uses the variables that the xml passes to:
<article>
<h1><?php echo $post_title ?></h1>
<?php echo $post_content ?>
<p><?php echo $post_author ?></p>
</article>
Xml file:
<?xml version="1.0" encoding="utf-8"?>
<posts>
<post>
<title>Hello World</title>
<author>tacticalsk8er</author>
<content>Hello world this is my blogging site</content>
</post>
<post>
<title>Hello Again</title>
<author>Nick Peterson</author>
<content><![CDATA[Hello Again world this is another test for my <b>blogging site</b>]]></content>
</post>
</posts>
Of course, you can access nodes in simplexml 'array-style':
$post = $xml->post[1]; // select second node
echo $post->title;
$xml represents the root-node <posts>, $xml->post selects posts/post.
see it working: http://3v4l.org/KOiv2
see the manual: http://www.php.net/manual/en/simplexml.examples-basic.php
I've had some success due to the help of StackOverflow community to modify a complex XML source for use with jsTree. However now that I have data that is usable, it is only so if i manually edit the XML to do the following :
Rename all <user> tags to <item>
Remove some elements before the first <user> tag
insert an 'encoding=UTF-8' into the XML opener
and lastly modify the <response> (opening XML tag) to <root>
XML File Example : SampleXML
I have read and read through so many pages on here and google but cannot find a method to achieve the above items.
Point (2) I have found out that by loading it via SimpleXML and using UNSET i can delete the portions I do not require, however I am still having troubles with the rest.
I thought I could perhaps modify the source with SimpleXML (that I am more familiar with) and then continue to modify the code via the help I had been provided before.
<?php
$s = file_get_contents('http://www.fluffyduck.com.au/sampleXML.xml');
$doc1 = simplexml_load_string($s);
unset($doc1->row);
unset($doc1->display);
#$moo = $doc1->user;
echo '<textarea>';
echo $doc1->asXML();
echo '</textarea>';
$doc = new DOMDocument();
$doc->loadXML($doc1);
$users = $doc->getElementsByTagName("user");
foreach ($users as $user)
{
if ($user->hasAttributes())
{
// create content node
$content = $user->appendChild($doc->createElement("content"));
// transform attributes into content elements
for ($i = 0; $i < $user->attributes->length; $i++)
{
$attr = $user->attributes->item($i);
if (strtolower($attr->name) != "id")
{
if ($user->removeAttribute($attr->name))
{
if($attr->name == "username") {
$content->appendChild($doc->createElement('name', $attr->value));
} else {
$content->appendChild($doc->createElement($attr->name, $attr->value));
}
$i--;
}
}
}
}
}
$doc->saveXML();
header("Content-Type: text/xml");
echo $doc->saveXML();
?>
Using recursion, you can create a brand new document based on the input, solving all your points at once:
Code
<?php
$input = file_get_contents('http://www.fluffyduck.com.au/sampleXML.xml');
$inputDoc = new DOMDocument();
$inputDoc->loadXML($input);
$outputDoc = new DOMDocument("1.0", "utf-8");
$outputDoc->appendChild($outputDoc->createElement("root"));
function ConvertUserToItem($outputDoc, $inputNode, $outputNode)
{
if ($inputNode->hasChildNodes())
{
foreach ($inputNode->childNodes as $inputChild)
{
if (strtolower($inputChild->nodeName) == "user")
{
$outputChild = $outputDoc->createElement("item");
$outputNode->appendChild($outputChild);
// read input attributes and convert them to nodes
if ($inputChild->hasAttributes())
{
$outputContent = $outputDoc->createElement("content");
foreach ($inputChild->attributes as $attribute)
{
if (strtolower($attribute->name) != "id")
{
$outputContent->appendChild($outputDoc->createElement($attribute->name, $attribute->value));
}
else
{
$outputChild->setAttribute($attribute->name, $attribute->value);
}
}
$outputChild->appendChild($outputContent);
}
// recursive call
ConvertUserToItem($outputDoc, $inputChild, $outputChild);
}
}
}
}
ConvertUserToItem($outputDoc, $inputDoc->documentElement, $outputDoc->documentElement);
header("Content-Type: text/xml; charset=" . $outputDoc->encoding);
echo $outputDoc->saveXML();
?>
Output
<?xml version="1.0" encoding="utf-8"?>
<root>
<item id="41">
<content>
<username>bsmain</username>
<firstname>Boss</firstname>
<lastname>MyTest</lastname>
<fullname>Test Name</fullname>
<email>lalal#test.com</email>
<logins>1964</logins>
<lastseen>11/09/2012</lastseen>
</content>
<item id="61">
<content>
<username>underling</username>
<firstname>Under</firstname>
<lastname>MyTest</lastname>
<fullname>Test Name</fullname>
<email>lalal#test.com</email>
<logins>4</logins>
<lastseen>08/09/2009</lastseen>
</content>
</item>
...
I know i have bothered all of you with my questions but i have a question about php and xml
i am trying to store all the values of the pages in xml so i would create a multilingual website
after searching i have got to a way but and i tried to alter it a little bit
there is my xml files:
en.xml:
<?xml version="1.0" encoding="UTF-8"?>
<main>
<!--Page Titles-->
<freeEaHdr>
<![CDATA[Get in the game!]]>
</freeEaHdr>
<freeEaSubhdr>
<![CDATA[Load up your Xperia™ PLAY with 4 exciting EA titles for<span style="color:#ff9c00;"> FREE</span>]]>
</freeEaSubhdr>
<!--Page Titles-->
</main>
and there is my ar.xml
<?xml version="1.0" encoding="UTF-8"?>
<main>
<!--Page Titles-->
<freeEaHdr>
<![CDATA[ادخل اللعبة]]>
</freeEaHdr>
<freeEaSubhdr>
<![CDATA[حمل الاكسبيريا الان]]>
</freeEaSubhdr>
<!--Page Titles-->
</main>
and i have created an select_lang.php
<?php
function select_lang(){
if(isset($_GET['lang'])){
$lang = $_GET['lang'];
if($lang == "en"){
$xml = simplexml_load_file("en.xml");
} else{
$xml = simplexml_load_file("ar.xml");
}
} else {
$xml = simplexml_load_file("en.xml");
}
return $xml;
}
?>
and the final page was index.php
<?php
include("select_lang.php");
select_lang();
?>
<div><?php echo $xml->freeEaHdr; ?></div>
<div><?php echo $xml-> freeEaSubhdr; ?></div>
english
arabic
now of course i get errors in index.php as for the main xml variable is not defined so if anybody has a solution
Thanks in advance
and sorry for bothering you
Your select_lang() function returns the created SimpleXML object $xml. You then try to use this object in your index.php file, but you haven't actually assigned the return value of select_lang() to anything.
Simply doing
$xml = select_lang();
instead of
select_lang();
will let you actually use the returned XML object in your index.php file.
try to:
<?php
include("select_lang.php");
$xml = select_lang(); //change this line
?>