how to write this correctly?
for($i=2;$i<5;$i++)
{
$items{$i} = $doc{$i}->getElementsByTagName('url');
}
got an error:
Fatal error: Call to a member function getElementsByTagName() on a non-object
Thanks,
bye
try :
$ndoc = 'doc'. $i;
$items[$i] = $$ndoc->getElementsByTagName('url');
or:
$ndoc = 'doc'. $i;
$items[$i] = ${$ndoc}->getElementsByTagName('url');
This test worked for me:-
$html1 = "<html><head><title>Test</title></head><body><p>Doc1 P1</p><p>Doc1 P2</p></body></html>";
$html2 = "<html><head><title>Test</title></head><body><p>Doc2 P1</p><p>Doc2 P2</p></body></html>";
$doc1 = new DOMDocument();
$doc1->loadHTML($html1);
$doc2 = new DOMDocument();
$doc2->loadHTML($html2);
for($i=1;$i<3;$i++){
var_dump(${'doc'.$i}->getElementsByTagName('p'));
}
So, your code should look like this:-
for($i=2;$i<5;$i++)
{
${'items'.$i} = ${'doc'.$i}->getElementsByTagName('url');
}
Unless you mean for $items to be an array, in which case it should look like this:-
for($i=2;$i<5;$i++)
{
$items[] = ${'doc'.$i}->getElementsByTagName('url');
}
Related
Can anyone help test this code and tell me what the error is?
The expected result is 01223658060102111111. but it is duplicated like this
01223658060102111111012236580601021111110122365806010211111101223658060102111111
here is my code
<?php
ini_set('user_agent', 'My-Application/2.5'); //without this file_get_content would not work
$saveURL = fopen("url.txt", "w");
$html = file_get_contents("http://www.carlist.my/used-cars/2592832/2004-toyota-camry-2-0.html");
$dom = new DOMDocument();
#$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$cont = $xpath->evaluate("//ul[contains(#class, 'list-contact')]/li");
foreach($cont as $con){
echo $con->nodeValue;
}
Replace this line to
$cont = $xpath->evaluate("//ul[contains(#class, 'list-contact')]/li");
to
$cont = $xpath->evaluate("//ul[contains(#class, 'list-contact')][1]/li");
#july77: How can I split them to get result 0122365806 and 060102111111
$arr = array();
foreach($cont as $con){
$arr[] = $con->nodeValue;
}
$first = $arr[0];
$second = $arr[1];
There are many posts on this topic but I did not get the required answer. Hence, I am here.
I have been getting Notice: Trying to get property of non-object in /opt/lampp/htdocs/amit/crawlnepalstock.php on line 49 error in my php page.
Here is my code
<?php
include_once('simple_html_dom.php');
error_reporting(E_ALL);
$html = file_get_html('http://nepalstock.com/datanepse/index.php');
$indexarray = array('s_no','stocksymbol', 'LTP', 'LTV', 'point_change', 'per_change', 'open','high', 'low', 'volume','prev_close');
$stocks = array();
$maincount = 0;
$tables = $html->find('table[class=dataTable]');
$str = $html->plaintext;
$matches = array();
foreach ($tables[0]->find('tr') as $elementtr) {
$count = 0;
$temp = array();
$anchor = $elementtr->children(1)->find('a',0);
$splits = preg_split('/=/', $anchor->href); **//line 49**
$temp['stocksymbol'] = isset($splits[1]) ? $splits[1] : null;
$temp['fullname'] = $elementtr->children(1)->plaintext;
$temp['no_of_trans'] = $elementtr->children(2)->plaintext;
$temp['max_price'] = $elementtr->children(3)->plaintext;
$temp['min_price'] = $elementtr->children(4)->plaintext;
$temp['closing_price'] = $elementtr->children(5)->plaintext;
$temp['total_share'] = $elementtr->children(6)->plaintext;
$temp['amount'] = $elementtr->children(7)->plaintext;
$temp['previous_close'] = $elementtr->children(8)->plaintext;
$temp['difference'] = $elementtr->children(9)->plaintext;
$stocks[] = $temp;
}
$html->clear();
unset($html);
echo '<pre>';
print_r($stocks);
echo '</pre>';
?>
I have not included simple_html_dom.php class as it is quite long. Your opinions are very much appreciated. You can find simple_html_dom.php file online in case http://sourceforge.net/projects/simplehtmldom/files/
You are trying to access property of non-object or from null object. e.g.
$obj = null;
echo $boject->first_name // this will produce same error as you are getting.
// another example may be
$obj = array();
echo $obj->first_name; // this will also produce same error.
In code sample Line 49 is not clear so you should check yourself this type of error on line 49.
This is happening because there is no longer a td[align="center"] tag found in the google.com document. Perhaps it was there when the code was first written.
So, what the others are saying about a non-object is true, but because the HTML was not found, there is not an object to use the ->plaintext method on.
As of 12/11/2020, if you change the URL found in line 6 of example_basic_selector.php to this:
$html = file_get_html('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_td_align_css');
And change this line
echo $html->find('td[align="center"]', 1)->plaintext . '';
to:
echo $html->find('td style="text-align:right"', 1)->plaintext. '';
the error will go away because the text it searches for is found, and thus the method works as intended.
Here is what I am trying to achieve : retrieve all products on a page and put them into an array. Here is the code I am using :
$page2 = curl_exec($ch);
$doc = new DOMDocument();
#$doc->loadHTML($page2);
$nodes = $doc->getElementsByTagName('title');
$noders = $doc->getElementsByClassName('productImage');
$title = $nodes->item(0)->nodeValue;
$product = $noders->item(0)->imageObject.src;
It works for the $title but not for the product. For info, in the HTML code the img tag looks like this :
<img alt="" class="productImage" data-altimages="" src="xxxx">
I have been looking at this (PHP DOMDocument how to get element?) but I still don't understand how to make it work.
PS : I get this error :
Call to undefined method DOMDocument::getElementsByclassName()
I finally used the following solution :
$classname="blockProduct";
$finder = new DomXPath($doc);
$spaner = $finder->query("//*[contains(#class, '$classname')]");
https://stackoverflow.com/a/31616848/3068233
Linking this answer as it helped me the most with this problem.
function getElementsByClass(&$parentNode, $tagName, $className) {
$nodes=array();
$childNodeList = $parentNode->getElementsByTagName($tagName);
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
$nodes[]=$temp;
}
}
return $nodes;
}
Theres the code and heres the usage
$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadHTML($html);
$content_node=$dom->getElementById("content_node");
$div_a_class_nodes=getElementsByClass($content_node, 'div', 'a');
function getElementsByClassName($dom, $ClassName, $tagName=null) {
if($tagName){
$Elements = $dom->getElementsByTagName($tagName);
}else {
$Elements = $dom->getElementsByTagName("*");
}
$Matched = array();
for($i=0;$i<$Elements->length;$i++) {
if($Elements->item($i)->attributes->getNamedItem('class')){
if($Elements->item($i)->attributes->getNamedItem('class')->nodeValue == $ClassName) {
$Matched[]=$Elements->item($i);
}
}
}
return $Matched;
}
// usage
$dom = new \DOMDocument('1.0');
#$dom->loadHTML($html);
$elementsByClass = getElementsByClassName($dom, $className, 'h1');
I am using PHP Domdocument to load my html. In my HTML, I have class="smalllist" two times. But, I need to load the first class elements.
Now, My PHP Code is
$d = new DOMDocument();
$d->validateOnParse = true;
#$d->loadHTML($html);
$xpath = new DOMXPath($d);
$table = $xpath->query('//ul[#class="smalllist"]');
foreach ($table as $row) {
echo $row->getElementsByTagName('a')->item(0)->nodeValue."-";
echo $row->getElementsByTagName('a')->item(1)->nodeValue."\n";
}
which loads both the classes.
But, I need to load only one class with that name.
Please help me in this. Thanks in advance.
DOMXPath returns a DOMNodeList which has a item() method. see if this works
$table->item(0)->getElementsByTagName('a')->item(0)->nodeValue
edited (untested):
foreach($table->item(0)->getElementsByTagName('a') as $anchor){
echo $anchor->nodeValue . "\n";
}
You can put a break within the foreach loop to read only from the first class. Or, you can do foreach ($table->item(0) as $row) {...
Code:
$count = 0;
foreach($table->item(0)->getElementsByTagName('a') as $anchor){
echo $anchor->nodeValue . "\n";
if( ++$count > 2 ) {
break;
}
}
another way rather than using break (more than one way to skin a cat):
$anchors = $table->item(0)->getElementsByTagName('a');
for($i = 0; $i < 2; $i++){
echo $anchor->item($i)->nodeValue . "\n";
}
This is my final code:
$d = new DOMDocument();
$d->validateOnParse = true;
#$d->loadHTML($html);
$xpath = new DOMXPath($d);
$table = $xpath->query('//ul[#class="smalllist"]');
$count = 0;
foreach($table->item(0)->getElementsByTagName('a') as $anchor){
$data[$k][$arr1[$count]] = $anchor->nodeValue;
if( ++$count > 1 ) {
break;
}
}
Working fine.
See my PHP:
file = "routingConfig.xml";
global $doc;
$doc = new DOMDocument();
$doc->load( $file );
function traverseXML($ElTag, $attr = null, $arrayNum = 'all'){
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
return $arr;
}else if(is_int($arrayNum)){
return $arr[$arrayNum];
}else{
return "Invalid $arrayNum value: ". $arrayNum;
};
}
echo traverseXML("Route", "type", 2);
XML is:
<Routes>
<Route type="source"></Route>
<Route></Route>
<Routes>
Error returned is:
Fatal error: Call to a member function getElementsByTagName() on a non-object
I'm not sure how to do this?
EDIT: Here is the actual code being used. I originally stripped it a little bit trying to make it easier to read, but I think my problem is related to using the function.
Your problem is that the global $doc; statement is outside the function, so the variable $doc is not defined inside the function.
This would fix it:
// ...
function traverseXML($ElTag, $attr = null, $arrayNum = 'all') {
global $doc;
// ...
...but
Global variables are bad news. They usually indicate poor design.
Really you should pass $doc in as an argument, like this:
function traverseXML($doc, $ElTag, $attr = null, $arrayNum = 'all'){
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
return $arr;
}else if(is_int($arrayNum)){
return $arr[$arrayNum];
}else{
return "Invalid $arrayNum value: ". $arrayNum;
};
}
$file = "routingConfig.xml";
$doc = new DOMDocument();
$doc->load( $file );
echo traverseXML($doc, "Route", "type", 2);
Although you might consider whether you need the function at all - if you don't use it anywhere else in you application, you might as well just do this:
$file = "routingConfig.xml";
$ElTag = "Route";
$attr = "type";
$arrayNum = 2;
$doc = new DOMDocument();
$doc->load( $file );
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
echo $arr;
}else if(is_int($arrayNum)){
echo $arr[$arrayNum];
}else{
echo "Invalid $arrayNum value: ". $arrayNum;
};
The $doc variable is not defined inside your function. You have two options:
Pass $doc as one of the function arguments, which is preferred.
Write global $doc; at the top of your function ... devs usually try to avoid globals.