ajax search box with xml database - php

I am trying to create a live search box on my website. I have an XML-file for a database. I've got the JavaScript part done, but I am a newbie at PHP and have some issues with this code I found on w3schools. My question is how do I modify the following code so that I only get the value of the "name" tag?
PHP code:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("links.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++)
{
$y=$x->item($i)->getElementsByTagName('title');
$z=$x->item($i)->getElementsByTagName('url');
if ($y->item(0)->nodeType==1)
{
//find a link matching the search text
if (stristr($y->item(0)->childNodes->item(0)->nodeValue,$q))
{
if ($hint=="")
{
$hint="<a href='" .
$z->item(0)->childNodes->item(0)->nodeValue .
"' target='_blank'>" .
$y->item(0)->childNodes->item(0)->nodeValue . "</a>";
}
else
{
$hint=$hint . "<br /><a href='" .
$z->item(0)->childNodes->item(0)->nodeValue .
"' target='_blank'>" .
$y->item(0)->childNodes->item(0)->nodeValue . "</a>";
}
}
}
}
}
// 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;
?>
XML:
<books>
<book>
<name>Harry Potter</name>
<quantity> 50 </quantity>
<price>19.90</price>
</book>
<book>
<name>Casino Royale</name>
<quantity> 50 </quantity>
<price>12.99</price>
</book>
<book>
<name>The Great Gatsby</name>
<quantity> 40 </quantity>
<price>14.90</price>
</book>
</books>
Thank you in advance for your answers! I really appreciate your help!

Here is an example of how you would do it:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("links.xml");
$books = $xmlDoc->getElementsByTagName("book");
//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 = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
$price = $book->getElementsByTagName("price")->item(0)->nodeValue;
$quantity = $book->getElementsByTagName("quantity")->item(0)->nodeValue;
echo "$name - $price - $quantity<br/>";
}
}
That will print out the $name, $price, and $quantity from the xml file for each book.

Related

How do I fix this PHP code?

I have to create a live search on a website. I have to use PHP, but I have never studied it and I am pretty much a beginner in programming.
I have an XML-file as a database and the aim is to get node values and display them as suggestions as a user types in something. The problem with this code is that it spits out all of the node values onto the web page.
Here is the PHP code:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("collection.xml");
$books = $xmlDoc->getElementsByTagName("book");
$q = $_GET["q"];
if (strlen($q) > 0) {
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
echo "$name <br/>";
}
}
if ($hint == "")
{
$response="no suggestion";
}
else
{
$response=$hint;
}
//output the response
echo $response;
?>
Here is the XML-file:
<books>
<book>
<name>Harry Potter</name>
<quantity> 50 </quantity>
<price>19.90</price>
</book>
<book>
<name>Casino Royale</name>
<quantity> 50 </quantity>
<price>12.99</price>
</book>
<book>
<name>The Great Gatsby</name>
<quantity> 40 </quantity>
<price>14.90</price>
</book>
</books>
Can someone please help me fix this issue so that I can continue working on my project. Thank you in advance for your time and help! Aprreciate it a lot!
The issue is here:
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
echo "$name <br/>";
}
Notice that you have a "foreach loop" here. The "$name=$book...." line simply reads the value of that particular XML node and assigns it to the $name variable. Then you are doing a call to echo $name. So in essence, all you're doing here is reading the value of the XML node and printing it. No part of your code compares the $name to your search query ($q). It seems that what you want to happen is only print out books that somehow match $q.
In order to do that we need to apply some logic to your foreach loop to only print out values that match $q.
Here is a suggestion:
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
// Let's only show this book if $q appears somewhere in $name.
if (strpos($name, $q) !== false && strpos($name, $q) >= 0)
{
echo $name . "<br />";
}
}

PHP XMLReader xml:lang

How can I read the xml:lang Value from this xml File???
<Catalog><Products>
<Product>
<Id>123</Id>
<Name xml:lang="en">name english product</Name>
<Description xml:lang="en">desc xyz</Description>
<Name xml:lang="de">name german</Name>
<Description xml:lang="de">desc germa</Description>
<Image num="1"><Url>pic.jpg</Url></Image>
<Image num="2"><Url>pic2.jpg</Url></Image>
</Product>
<Product>...
I want the value of the xml:lang="de" - Tag and the Image-Values.
Does anybody have an idea???
Thanx :-)
Update: I parse the xml like this, but how do i get this values???
$datei = "test.xml";
$z = new XMLReader;
$z->open($datei);
$doc = new DOMDocument;
while ($z->read() && $z->name !== 'Product');
$i = 0; while ($z->name === 'Product')
{ $i++;
$node = simplexml_import_dom($doc->importNode($z->expand(), true));
...
I think this should do it.
$simpleXml = new SimpleXMLElement(file_get_contents($datei));
foreach ($simpleXml->Products->Product as $product) {
$name = $product->xpath('Name[#xml:lang="en"]')[0];
echo $name . "\n";
foreach($product->Image as $img) {
echo $img->Url . "\n";
}
}
xpath use to many resurses. You can scan it, taking needed nodes. In the code you will see how take name and value of nodes and attributes, which have prefix.
$simpleXml = new SimpleXMLElement(file_get_contents($datei)));
foreach ($simpleXml->Products->Product as $products) // list of nodes with same name
foreach($products as $product) { // every node
if ($product->getName() === 'Image') { // for image take child
echo $product->Url->getName() . " = " . $product->Url ."\n";
$attrs = $product->attributes(); // Attribute without prefix
if(isset($attrs['num'])) echo " num = " . $attrs['num'] . "\n";
}
else echo $product->getName() . " = " . $product ."\n";
$attrs = $product->attributes('xml', true); // if 2nd true, 1st is prefix
if(isset($attrs['lang'])) echo " lang = " . $attrs['lang'] . "\n";
}
result
Id = 123
Name = name english product
lang = en
Description = desc xyz
lang = en
Name = name german
lang = de
Description = desc germa
lang = de
Url = pic.jpg
num = 1
Url = pic2.jpg
num = 2

Reading xml with attributes in php

I have a xml. as shown in the attachment ..
How can I read the contents via php
http://agency.lastminute-hr.com/slike/xml_read1.jpg "XML"
Now I read this xml:
<?
$request = new SimpleXMLElement('<HotelInfoRequest/>');
$request->Username = 'SERUNCD';
$request->Password = 'TA78UNC';
$request->HotelID = '123';
$url = "http://wl.filos.com.gr/services/WebService.asmx/HotelInfo";
$result = simplexml_load_file($url . "?xml=" . urlencode($request->asXML()));
function RecurseXML($xml,$parent="")
{
$child_count = 0;
foreach($xml as $key=>$value)
{
$child_count++;
if(RecurseXML($value,$parent.".".$key) == 0) // no childern, aka "leaf node"
{
print($parent . "." . (string)$key . " = " . (string)$value . "<BR>\n");
}
}
return $child_count;
}
RecurseXML($result);
?>
this result look:
..
..
.Response.Hotels.Hotel.Rooms.Room.Quantity = 0
.Response.Hotels.Hotel.Rooms.Room.MaxPax = 3
.Response.Hotels.Hotel.Rooms.Room.MinPax = 2
.Response.Hotels.Hotel.Rooms.Room.RoomType.languages.lang = Room Double Standard
.Response.Hotels.Hotel.Rooms.Room.RoomType.languages.lang = Camera single standard
...
...
I need you to display the value and adttribut
<Rooms>
<Room ID = "5556">
<Quantity> 0 </ Quantity>
<MaxPax> 3 </ MaxPax>
<MinPax> 2 </ MinPax>
<Roomtype> </ roomtype>
</ Room>
....
..
Try (the first part is only for testing):
$string = <<<XML
<?xml version='1.0'?>
<Rooms>
<Room ID = "5556">
<Quantity> 0 </Quantity>
<MaxPax> 3 </MaxPax>
<MinPax> 2 </MinPax>
<Roomtype> </Roomtype>
</Room>
</Rooms>
XML;
$result = simplexml_load_string($string);
function RecurseXML($xml,$parent=".Response.Hotels.Hotel.Rooms"){
$children = $xml->children();
if ( empty($children) ) {
print($parent . "." . $xml->nodeName . " = " . (string)$xml . "<BR>\n");
}
else {
foreach($children as $key=>$value) {
RecurseXML($value, $parent . "." . $key);
}
}
}
RecurseXML($result);

handle syntax error, unexpected T_IF in PHP

I need to create a search of string in an XML file on all nodes.
---catalog.xml---
<?xml version="1.0" encoding="ISO-8859-1"?>
<Catalog>
<Category>
<Name>Biscuit</Name>
<Location>
<Id>Butter</Id>
<Description>The butter biscuit cost $10 per pack</Description>
</Location>
<Location>
<Id>Chocolate</Id>
<Description>The chocolate biscuit cost $20 per pack</Description>
</Location>
</Category>
<Category>
<Name>Cake</Name>
<Location>
<Id>Cup</Id>
<Description>This is a cup cake</Description>
</Location>
<Location>
<Id>Slice</Id>
<Description>This is a slice cake</Description>
</Location>
</Category>
</Catalog>
---search.php---
<?php
$catalog = simplexml_load_file("catalog.xml");
$category = $catalog->Category;
$location = $category->Location;
foreach($location->Description as $desc)
{
$string = string($desc);
$find = 'chocolate';
$result = strpos($string, $find)
if ($result !== false)
{
echo $result;
}
else
{
echo "No Result";
}
}
?>
The error I received is:
Parse error: syntax error, unexpected T_IF on line 14
Since there is "chocolate" at node and Node, I need to display both node result.
----New Amended Code / 20 Nov 2012---
<?php
$catalog = simplexml_load_file("catalog.xml");
$find = "chocolate";
$lcFind = strtolower($find);
$ll = implode('', range('a', 'z'));
$ul = strtoupper($ll);
$xpath_result = $catalog->xpath("//*[contains(translate(text(), '$ul','$ll'),'$lcFind')]");
if ($xpath_result) {
foreach ($xpath_result as $res) {
$category = $catalog->Category;
$name = $category->Name;
$loc = $category->Location;
$id = $loc->Id;
echo "Category: ", $name, "<br />";
echo "ID: ", $id, "<br />";
echo "Description :", $res, "<br />";
}
}
else {
echo "No matching descriptions found for word '<i>$find</i>'<br />";
}
?>
Result (Wrong):
Category: Biscuit
ID: Butter //This should be "Chocolate"
Description :Chocolate //This should be the description for "Chocolate"
Category: Biscuit
ID: Butter
Description :The chocolate biscuit cost $20 per pack
It should be...
$result = strpos($string, $find);
You should finish your statements with semicolons in PHP. And it'd probably be quite a nice idea using IDE (or even a text editor) with PHP syntax check.
... Yet there's only the beginning of the problem (and I'm not talking about non-existing string function here). See, with this code you're trying to search for some term only in descriptions of the first location of the first category. If that's actually the task, ok, but somehow I feel your original intent is better expressed with this:
$found = false;
foreach ($catalog->Category as $category) {
foreach($category->Location as $location) {
$description = "{$location->Description}";
$result = strpos($description, $find);
if ($result !== FALSE) {
echo "Word '<i>$find</i>' found in <b>$description</b> at position " . ($result + 1) . '.<br />';
$found = true;
}
}
}
if (! $found) {
echo "No matching descriptions found for word '<i>$find</i>'<br />";
}
And even this can be optimized with XPath - especially if you actually don't need to echo the position:
$xpath_result = $catalog->xpath("//Description[contains(text(),'$find')]");
if ($xpath_result) {
foreach ($xpath_result as $res) {
echo "Word '<i>$find</i>' found in <b>$res</b><br />";
}
}
else {
echo "No matching descriptions found for word '<i>$find</i>'<br />";
}
... or, for case-insensitive search:
$lcFind = strtolower($find);
$ll = implode('', range('a', 'z'));
$ul = strtoupper($ll);
$xpath_result = $catalog->xpath("//*[contains(translate(text(), '$ul', '$ll'),'$lcFind')]");
... // the rest of code is the same

php simple xml how to read multiple nodes with different child node levels

I have an xml file that has different named nodes and multi level child nodes (that are different between each node.) How should I access the data? Will it require many nested for loops?
Here is a sample of the xml code:
<start_info>
<info tabindex="1">
<infonumber>1</infonumber>
<trees>green</trees>
</info>
</start_info>
<people>
<pe>
<people_ages>
<range number="1">
<age value="1">1</age>
<age value="2">2</age>
</range>
</people_ages>
</pe>
</people>
Here is my code so far:
$xml = simplexml_load_file("file.xml");
echo $xml->getName() . "start_info";
foreach($xml->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
}
Here is some example code that I hope can point you in the right direction. Essentially, it is walking the DOMDocument echoing the element name and values. Note that the whitespace between the elements is significant, so for the purposes of the demo, the XML is compacted. You may find a similar issue loading from a file, so if you are not getting the expected output you might need to strip whitespace nodes.
You could replace the //root/* with a different XPath for example //people if you only wanted the <people> elements.
<?php
$xml = <<<XML
<root><start_info><info tabindex="1"><infonumber>1</infonumber><trees>green</trees></info></start_info>
<people><pe><people_ages><range number="1"><age value="1">1</age><age value="2">2</age></range></people_ages></pe></people>
</root>
XML;
$dom = new DOMDocument();
$dom->recover = true;
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$nodelist = $xpath->query('//root/*');
foreach ($nodelist as $node) {
echo "\n$node->tagName";
getData($node);
}
function getData($node) {
foreach ($node->childNodes as $child) {
if ($child->nodeType == XML_ELEMENT_NODE) {
echo ($child->tagName === '' ? '' : "\n").$child->tagName;
}
if ($child->nodeType == XML_TEXT_NODE) {
echo '->'.$child->nodeValue;
}
if ($child->hasChildNodes()) {
getData($child); // recursive call
}
}
}
?>
check this
$xml_file = 'file.xml';
$xmlobj = simplexml_load_file($xml_file);
echo $xmlobj->getName() . 'start_info<br />';
foreach($xmlobj->children() as $childs) {
echo $childs->getName(). ': '. '<br />';
if($childs->count()>1) {
foreach($childs as $child) {
echo $child->getName(). ': '. $child. '<br />';
}
}
}

Categories