php echo DOM Elements as strings - php

I have used the following code to store a small timetable in an array. I am trying to return specific elements of the array but get the error Cannot use object of type DOMElement as array.
I would be grateful if somebody could tell me how to retrieve the nodeValue of certain elements and display them.
$doc = new DOMDocument();
$doc->loadHTML($timetable);
$headers = $doc->getElementsByTagName('th');//' missed which is typo i think
$cells = $doc->getElementsByTagName('td');//' missed which is typo i think
$array = iterator_to_array($cells);
I can loop through this and display the entire table with a for loop, and that's fine, but I can't return 1 value from the array:
for ($i=0; $i<=5; $i++){
$val = $array[$i];
echo $val[1]->nodeValue;
}
And this returns the error I mentioned above.

Related

Php, new keys and values added inside loop dissapear outside loop

For a school assignment I'm trying to split stockitems with product details like colour and size in the title into groups of stockitems with different variants. I've got as far as having them all split, but I just can't figure out how to add this information to the $stockItem array. ($stockItem is inside the array $stockItemGroup which is inside the array $stockItemGroups).
When I try to add information to the array inside the loop, I cannot access that information outside the loop. If I use print_r on the entire array after this loop has completed the new information is not displayed.
for($i = 0; $i < count($stockItemGroup); $i++){
$stockItem = $stockItemGroup[$i];
$restString = str_replace($similarString, "", $stockItem['StockItemName']);
$colour = getColour($restString, $allColours);
$restVariant = getRestVariant($restString, $allColours);
$stockItemGroup[$i]['Colour'] = $colour;
$stockItemGroup[$i]['RestVariant'] = $restVariant;
$stockItemGroup[$i]['NewItemName'] = createNewItemName($colour, $restVariant, $stockItem['StockItemName']);
}
I have tried both in a foreach and a for loop (I read that a foreach does some copying, so I thought that might cause it). but to no avail.
I have also obviously tried
$stockItem['Colour'] = $colour;
$stockItem['RestVariant'] = $restVariant;
$stockItem['NewItemName'] = createNewItemName($colour,
$restVariant,
$stockItem['StockItemName']);
But that did not change anything either.
I am a total Php noob, so it might be very obvious, any help would be appreciated.
EDIT:
this loop is inside a method which is called in this loop:
$stockItemGroups = getStockItemGroups();
foreach ($stockItemGroups as $stockItemGroup){
addVariants($stockItemGroup);
//writeNewGroup($stockItemGroup);
}
foreach ($stockItemGroups as &$stockItemGroup){ Pass the array as a reference – RiggsFolly

Printing multiple websites arrays

Unfortunately, after research I still couldn't find the answer for my issue.
The issue is that I cannot print data from multiple pages. Data is printed only once. Perhaps I am missing silly mistake here, which you could help me find it.
$cycles=10;
$listValue=0;
for ($cy = 0; $cy < $cycles; $cy++){
$html = file_get_contents("http://www.website.com/rate/today.aspx?d=02.03.2015&r=". $listValue ."01&c=#");
$dom = new DOMDocument;
#$dom->loadHTML($html);
$tables = $dom->getElementsByTagName('td');
$data = array();
while($table = $tables->item($i++))
{
//stuff
}
foreach($data as $item)
{
echo "Rank - " . $item['rank'] . "</br>";
}
$listValue++;
echo $listValue."<br>";
}
So basically, I am able to print data only of first page.
Declare the collection variable before the first loop $whatWasCollected = "";
Assign the collected data to a variable at the end of the first loop & Append to the variable each time.
$whatWasCollected .= "This is what I want to print..."
Get rid of the last loop and just echo the complete string.
echo $whatWasCollected;
Just a suggestion. Try it out and let me know if it works seem like and interesting question to me.

php simple xml, loop hrough object, put string in array

I am getting an XML error for some reason, even though this(beginner) code does what i want it to do.
It fetches strings into an array.
Line 11 results in "Notice: Trying to get property of non-object in D:\pam\w\www\mp\p\lasxml.php on line 11"
<?php
$xml = new DOMDocument( "1.0", "ISO-8859-1" );
$xml = simplexml_load_file('http://www.myepisodes.com/rss.php?feed=mylist&showignored=0&sort=asc&uid=Demerzel&pwdmd5=c6ed54b98a82b1----ac58147cedbde5');
$allaFullStringfranxml = array();
$i = 0;
do{
$allaFullStringfranxml[] = $xml->channel->item[$i]->title;
++$i;
}while(($xml->channel->item[$i]->title) != null);
I'm not sure why you are using do-while loop, I think in this case foreach will be better - do while loop is running at least once (even if there is no item). Also you are incrementing $i variable and then checking if title title of item with $i index is null - you shouldn't do that without checking if that item really exists. That should work better for you:
foreach ($xml->channel->item as $item) {
$allaFullStringfranxml[] = (string)$item->title;
}
You can also notice here that I'm doing (string)$item->title - that will convert title node to string, in other case you'll store node object.

Accounting for missing array keys, within PHP foreach loop

I'm parsing a document for several different values, with PHP and Xpath. I'm throwing the results/matches of my Xpath queries into an array. So for example, I build my $prices array like this:
$prices = array();
$result = $xpath->query("//div[#class='the-price']");
foreach ($result as $object) {
$prices[] = $object->nodeValue; }
Once I have my array built, I loop through and throw the values into some HTML like this:
$i = 0;
foreach ($links as $link) {
echo <<<EOF
<div class="the-product">
<div class="the-name"><a title="{$names[$i]}" href="{$link}" target="blank">{$names[$i]}</a></div>
<br />
<div class="the-image"><a title="{$names[$i]}" href="{$link}" target="blank"><img src="{$images[$i]}" /></a></div>
<br />
<div class="the-current-price">Price is: <br> {$prices[$i]}</div>
</div>
EOF;
$i++; }
The problem is, some items in the original document that I'm parsing don't have a price, as in, they don't even contain <div class='the-price'>, so my Xpath isn't finding a value, and isn't inserting a value into the $prices array. I end up returning 20 products, and an array which contains only 17 keys/values, leading to Notice: Undefined offset errors all over the place.
So my question is, how can I account for items that are missing key values and throwing off my arrays? Can I insert dummy values into the array for these items? I've tried as many different solutions as I can think of. Mainly, IF statements within my foreach loops, but nothing seems to work.
Thank you
I suggest you look for an element inside your html which is always present in your "price"-loop. After you find this object you start looking for the "price" element, if there is none, you insert an empty string, etc. into your array.
Instead of directly looking for the the-price elements, look for the containing the-product. Loop on those, then do a subquery using those nodes as the starting context. That way you get all of the the-product nodes, plus the prices for those that have them.
e.g.
$products = array();
$products = $xpath->query("//div[#class='the-product']");
$found = 0 ;
foreach ($products as $product) {
$products[$found] = array();
$price = $xpath->query("//div[#class='the-price']", $product);
if ($price->length > 0) {
$products[$found] = $price->item(0)->nodeValue;
}
$found++;
}
If you don't want to show the products that don't have a price attached to them you could check if $prices[$i] is set first.
foreach($links AS $link){
if(isset($prices[$i])){
// echo content
}
}
Or if you wanted to fill it will dummy values you could say
$prices = array_merge($prices,
array_fill(count($prices), count($links)-count($prices),0));
And that would insert 0 as a dummy value for any remaining values. array_fill starts off by taking the first index of the array (so we start one after the amount of keys in $prices), then how many we need to fill, so we subtract how many are in $prices from how many are in $links, then we fill it with the dummy value 0.
Alternatively you could use the same logic in the first example and just apply that by saying:
echo isset($prices[$i]) ? $prices[$i] : '0';
Hard to understand the relation between $links and $prices with the code shown. Since you are building the $prices array without any relation to the $links array, I don't see how you would do this.
Is $links also built via xpath? If so, is 'the-price' div always nested within the DOM element used to populate $links?
If it is you could nest your xpath query to find the price within the query used to find the links and use a counter to match the two.
i.e.
$links_result = $xpath->query('path-to-link')
$i = 0
foreach ($links_result as $link_object) {
$links[$i] = $link_object->nodeValue;
// pass $link_object as context reference to xpath query looking for price
$price_result = $xpath->query('path-to-price-within-link-node', $link_object);
if (false !== $price_result) {
$prices[$i] = $price_result->nodeValue;
} else {
$prices[$i] = 0; // or whatever value you want to show to indicate that no price was available.
}
$i++;
}
Obviously, there could be additional handling in there to verify that only one price value exists per link node and so forth, but that is basic idea.

How to index XML elements in PHP?

I am dummy to PHP and XML, so please be patient if my question seems dumb.
I want to know how to index the XML elements so that I can access them. I am planning to put them into an array. However, I don't know how to get the number of elements returned.
Here are the codes:
exer.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<actionstars>
<name>Jean Claude Van Damme</name>
<name>Scott Adkins</name>
<name>Michael Jai White</name>
<name>Dolph Lundgren</name>
<name>Tom Cruise</name>
<name>Michael Worth</name>
</actionstars>
index.php
<?php
$dom = new DomDocument();
$dom->load("exer.xml");
$names = $dom->getElementsByTagName("name");
echo count($names);
foreach($names as $name) {
print $name->textContent . "<br />";
}
?>
When I do the echo count($names); it returns 1, which is obviously not the number of elements. Please help.
Have a look at the return value of getElementsByTagName, which will be a DOMNodeList.
Also for your problem you could do something like:
$names = array();
foreach ($dom->getElementsByTagName("name") as $nameNode) {
$names[] = $nameNode->nodeValue;
}
You don't have to actually check the return value of getElementsByTagName, for it will allways be a DOMNodeList. This way you can use it directly in the foreach-loop whithout assigning unneeded variables.
What you have to check, is the size of $names, after the loop.

Categories