PHP XML echoing values contained in a node - php

I have a XML doc , with 3 article nodes in it , each Article contains :
Title
Image
Link
I need to be able to get the Title/Image/Link values out of the node.
$query = $xpath->query('//section/article');
foreach($query as $currentArticle => $artContents):
print_r( $artContents->title);
endforeach
;
This doesn't work for me, I can use ->NodeName and nodeValue , but they dont drill down enough , just display 'article' or the whole contents respectively.
To explain more:
My XML is
<article>
<title>Title </title>
<link>http:// </link>
<img>image src </img>
</article>
and the output I require is :
Title->Title
Link->http://
etc.
Update to explain :
foreach($query as $articles):
foreach($articles->childNodes as $childNode) {
if ($childNode->nodeType === XML_ELEMENT_NODE) {
$stored = $childNode->nodeValue;
array_push( $availAds, $stored );
}
}
endforeach;
is what I currently have thanks to Gordon . This though makes my array look like:
//previous values:
}
["1300884672_071.jpg"]=>
array(3) {
["image"]=>
string(30) "1300884672_071.jpg"
["title"]=>
string(6) "secind title"
["link"]=>
string(10) "grtgrtgrtg"
}
["1300884618_071.jpg"]=>
array(3) {
["image"]=>
string(30) "1300884618_071.jpg"
["title"]=>
string(5) "first title"
["link"]=>
string(10) "http://www.google.com"
}
//updated values that
[0]=>
string(6) "My Title"
[1]=>
string(89) "/1300961550.jpg"
[2]=>
string(22) "rtherherhgerg thursada"
[3]=>
string(20) "custome 222222222222"
I obviously need my array to be consistent, but cannot work out how to do that. Thanks for your patience.
Bob

I'm still not sure what the problem is, but are you looking for
foreach($query as $articles):
foreach($articles->childNodes as $childNode) {
if ($childNode->nodeType === XML_ELEMENT_NODE) {
printf("%s->%s%s", $childNode->nodeName, $childNode->nodeValue, PHP_EOL);
}
}
}
This will iterate over all the DOMElement nodes that are direct children of the $article nodes returned in the query and print them in this format "nodename->nodevalue" and a newline.

Related

json_encode creates useless zero keys

I am writing an API to output an adress book, which I get the output as a XML. The output is JSON.
What's my problem?
I looping through the entries, which I get from an XML file and store it in an array. That means, that every entry includes an contact:
$xml = new SimpleXMLElement("adressbook.xml"); // <-- Only an example URL
$totalResults = $xml->children('openSearch', true)->totalResults;
$contacts=array();
foreach($xml->entry as $contact){
$tel = $contact->children('tel', true);
$entry = array(
"type"=>$tel->type,
"name"=>$tel->name,
"firstname"=>$tel->firstname,
"street"=>$tel->street,
"streetno"=>$tel->streetno,
"zip"=>$tel->zip,
"city"=>$tel->city,
"canton"=>$tel->canton,
"country"=>$tel->country,
"phone"=>$tel->phone
);
array_push($contacts,$entry);
}
After this I want to echo the array in json. I do this with json_encode.
But there is the problem. Instead of giving the results directly, it shows me following results:
The zero's which are red marked should not exist.
What I tried
I researched in the internet and found in the docs and in a few posts on Stack Overflow the JSON_FORCE_OBJECT attribute for json_encode.
http://php.net/manual/en/function.json-encode.php
Now my function looks like this:
echo json_encode($contacts,JSON_FORCE_OBJECT);
But I still get the zero's.
Here is also a small example of my XML:
<entry>
<updated>2017-04-11T02:00:00Z</updated>
<published>2017-04-11T02:00:00Z</published>
<title type="text">Mustermann, Max</title>
<tel:type>Person</tel:type>
<tel:name>Mustermann</tel:name>
<tel:firstname>Max</tel:firstname>
<tel:street>Musterstrasse</tel:street>
<tel:streetno>17</tel:streetno>
<tel:zip>8000</tel:zip>
<tel:city>Zürich</tel:city>
<tel:canton>ZH</tel:canton>
<tel:country>ch</tel:country>
<tel:phone>+123456789</tel:phone>
</entry>
What is going wrong?
UPDATE:
Here is the var_dump:
object(SimpleXMLElement)#6 (15) { ["type"]=> string(12) "Organisation" ["name"]=> string(28) "*******" ["occupation"]=> string(57) "*******" ["street"]=> string(11) "Musterstrasse" ["streetno"]=> string(1) "17" ["zip"]=> string(4) "8000" ["city"]=> string(5) "Zürich" ["canton"]=> string(2) "ZH" ["country"]=> string(2) "ch" ["phone"]=> string(12) "+123456789" }
One approach is to use strval to convert each object to a string
$xml = new SimpleXMLElement("adressbook.xml"); // <-- Only an example URL
$totalResults = $xml->children('openSearch', true)->totalResults;
$contacts=array();
foreach($xml->entry as $contact){
$tel = $contact->children('tel', true);
$entry = array(
"type"=>strval($tel->type),
"name"=>strval($tel->name),
"firstname"=>strval($tel->firstname,)
"street"=>strval($tel->street),
"streetno"=>strval($tel->streetno),
"zip"=>strval($tel->zip),
"city"=>strval($tel->city),
"canton"=>strval($tel->canton),
"country"=>strval($tel->country),
"phone"=>strval($tel->phone)
);
array_push($contacts,$entry);
}

SimpleXMLElement get non-attribute values

I have the following SimpleXMLElement:
object(SimpleXMLElement)#10 (3) {
["#attributes"]=> array(3) {
["id"]=> string(8) "18022352"
["name"]=> string(14) "The Salmon Man"
["slug"]=> string(14) "the-salmon-man"
}
["bids"]=> object(SimpleXMLElement)#11 (1) {
["price"]=> array(1) {
[0]=> object(SimpleXMLElement)#13 (1) {
["#attributes"]=> array(4) {
["decimal"]=> string(4) "9.60"
["percent"]=> string(5) "10.42"
["backers_stake"]=> string(5) "40.36"
["liability"]=> string(6) "347.00"
}
}
}
}
["offers"]=> object(SimpleXMLElement)#12 (1) {
["price"]=> array(1) {
[0]=> object(SimpleXMLElement)#15 (1) {
["#attributes"]=> array(4) {
["decimal"]=> string(4) "9.20"
["percent"]=> string(5) "10.87"
["backers_stake"]=> string(5) "85.35"
["liability"]=> string(5) "10.41"
}
}
}
}
}
Why does this work:
$horse[0]['name']
but this doesn't:
$horse[0]['bids'] // also tried $horse['bids'] and other ways
I can get the values like below but I was hoping to search the smaller object:
$xml->xpath("//odds/event[#id='$matchid']/market[#slug='to-win']/contract[#name='$pony']/bids"); // $pony == $horse[0]['name']
It's often easier to look at the XML itself, rather than a print_r of the SimpleXML object. In this case, you have something like this:
<horse id="18022352" name="The Salmon Man" slug="the-salmon-man">
<bids>
<price decimal="9.60" percent="10.42" backers_stake="40.36" liability="347.00" />
</bids>
<offers>
<price decimal="9.60" percent="10.42" backers_stake="40.36" liability="347.00" />
</offers>
</horse>
The bids item is an element, and as discussed in the SimpleXML Basic Usage guide, you access child elements with ->foo notation, whereas attributes use ['foo'] notation.
So if $horse is that <horse> element, you need:
$name = $horse['name'];
$bids = $horse->bids;
Note that this is equivalent to explicitly asking for the first child called bids; both forms will work regardless of whether there is actually more than one identically name element:
$bids = $horse->bids[0];
Now there are presumably one or more <price> elements in practice, so you might want to loop over, and then echo each decimal attribute. That would look like this:
foreach ( $horse->bids->price as $price ) {
echo $price['decimal'];
}
Again, this loop will work fine with only one <price>, it will just just loop once. If there is only ever one price, or you only care about the first one, you could just write:
echo $horse->bids->price['decimal'];
Which is equivalent to:
echo $horse->bids[0]->price[0]['decimal'];
Or of course either of these:
echo $horse->bids[0]->price['decimal'];
echo $horse->bids->price[0]['decimal'];
The number of different ways of getting to the same place is one reason I don't recommend relying too much on print_r output. Another is that it sometimes can't display everything that's in the XML, which doesn't mean that data isn't available if you ask for it.

How to randomize images from albums [duplicate]

This question already has answers here:
Shuffle an array in PHP
(6 answers)
Closed 9 years ago.
I'm trying to make an image gallery. On the index file I want to show the albums with the images, see; http://www.robcnossen.nl/
I want to randomize the images that are inside these albums but I get all sorts of errors like:
warning: rand() expects parameter 1 to be long, string given in.
My code is;
foreach ($albums as $album) {
?><div><h2><?php
echo'',$album['name'], '';?> </h2><?php
echo'<img src="uploads/thumbs/', $album["id"], '/', $album["imagename"],'" title="" />';
?></div><?php
}
The $album["imagename"] are the images inside the albums and I want to randomize this part. I tried for example:
rand($album["imagename"], 0)
but that gives an error.
I also tried shuffle;
foreach ($albums as $album) {
shuffle($album["imagename"]);
?><div><h2><?php
echo'',$album['name'], '';?></h2><?php
echo'<img src="uploads/thumbs/', $album["id"], '/', $album["imagename"],'" title="" />';
?></div><?php
}
But also there I get only errors.
Can anybody help me with this?
var_dump($albums);
gives
array(2) {
[0]=> array(8) {
["id"]=> string(1) "8"
["timestamp"]=> string(10) "1373890251"
["name"]=> string(7) "Holland"
["description"]=> string(19) "Fantastische foto's"
["count"]=> string(1) "2"
["imagename"]=> string(38) "KONICA MINOLTA DIGITAL CAMERA_428.jpeg"
["image"]=> string(2) "63"
["ext"]=> string(0) ""
}
[1]=> array(8) {
["id"]=> string(1) "9"
["timestamp"]=> string(10) "1376914749"
["name"]=> string(6) "Belgie"
["description"]=> string(11) "Mooi Belgie"
["count"]=> string(1) "2"
["imagename"]=> string(12) "PICT0170.JPG"
["image"]=> string(2) "66"
["ext"]=> string(0) ""
}
}
as result.
shuffle should work for you, but not if you put it inside the foreach loop, like your example code. You need to shuffle before you start the loop. Also, shuffle needs to be called with the array itself, not an item of the array:
shuffle($albums);
foreach ($albums as $album) {
...
}
you should shuffle array out side the loop
<?php
shuffle($albums);
foreach ($albums as $album)
{
?><div><h2>
<?php
echo'',$album['name'], '';
?>
</h2>
<?php
echo'<img src="uploads/thumbs/', $album["id"], '/', $album["imagename"],'" title="" />';
?>
</div>
<?php
}

Turning an array element into a link, which acts like a "POST" method in a form.

I have a webpage which contains a form, like the following:
<Form action=”search.php” method=”POST”>
<fieldset>
<legend> Enter your search below </legend>
<textarea name=”query”> </textarea>
</fieldset>
</form>
The users text is read from query and search results are displayed using code in the following section:
if ($_POST['query'])
{
//Users query is read and results from a search API are displayed
}
The next thing that happens is that a list of synonyms are generated, stored in a multidimensional array called $synonyms which I have displayed in a left-hand-navigation bar, using the code shown below. $newline prints a newline (as the variable name suggests)
Example of a $synonyms array:
array(3)
{ [0]=> array(2)
{ [0]=> string(9) "chelonian"
[1]=> string(17) "chelonian reptile" }
[1]=> array(6)
{ [0]=> string(7) "capsize"
[1]=> string(11) "turn turtle"
[2]=> string(8) "overturn"
[3]=> string(9) "turn over"
[4]=> string(8) "tip over"
[5]=> string(9) "tump over" }
[2]=> array(4)
{ [0]=> string(4) "hunt"
[1]=> string(3) "run"
[2]=> string(9) "hunt down"
[3]=> string(10) "track down" }
}
Code used to output the array:
foreach ($synonyms as $test)
{ foreach ($test as $test2)
{
echo $test2.$newline.$newline;
}
}
What I want to happen is:
Turn each synonym into a clickable link..if the user clicks the synonym "capsize", the word capsize is sent to the section where the synonym(previously query) is read and processed into results.. ie. back to this section:
if ($_POST['query'])
{
// Synonym is read and results from a search API are displayed
// Previously 'query' was read here
// The cycle continues again
}
Any ideas or suggestions on this one would be great, thanks guys.
You should use GET in search form. Then list synonyms as shown below
foreach ($synonyms as $test)
{ foreach ($test as $test2)
{
// I used <br/> for newline
printf('%1$s<br/>', $test2);
}
}
Edit: And obviously, you should replace $_POST['query'] with $_GET['query']

PHP - Simple XML attributes problem

I use PHP and Simple XML.
I use a loop that does not work like expected:
foreach($item->Image->attributes()->source as $key => $value)
{
echo $value;
}
In the foreach I try to tell that I want to get the "source" of the image which is listed in the attributes.
$item above is created with a loop around my code above foreach($xml_content->Section->Item as $item {}, (if you need to know where it came from)
My object looks like this:
object(SimpleXMLElement)#36 (4) {
["Text"]=>
string(15) "Vinbergs socken"
["Description"]=>
string(73) "Vinbergs socken ingick i Faurås härad och ligger i Falkenbergs kommun.
"
["Url"]=>
string(44) "http://sv.wikipedia.org/wiki/Vinbergs_socken"
["Image"]=>
object(SimpleXMLElement)#38 (1) {
["#attributes"]=>
array(3) {
["source"]=>
string(113) "http://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Faur%C3%A5s_Vinberg.svg/50px-Faur%C3%A5s_Vinberg.svg.png"
["width"]=>
string(2) "50"
["height"]=>
string(2) "41"
}
}
}
What is wrong with my loop in the beginning of my post?
Your are trying to iterate a string, not an array
$item->Image->attributes()->source
To iterate all the attributes of the Image element, use
foreach ($item->Image->attributes() as $attributeName => $attributeValue) {
If you just want to output the value of the source attribute, do not iterate but use the shorthand
echo $item->Image['source']
See this demo and the SimpleXml Basic Usage Examples in the PHP Manual

Categories