4

I am trying to fetch the alt tag from the following img tag...

<div class="localImage">

    <a href="/Electronic-Deals/b/ref=amb_link_185249707_2?ie=UTF8&amp;node=4192584031&amp;pf_rd_m=A1VBAL9TL5WCBF&amp;pf_rd_s=center-new-12&amp;pf_rd_r=07C4YQ4KZ15MZJQBT2PD&amp;pf_rd_t=701&amp;pf_rd_p=736512207&amp;pf_rd_i=20">

    <img src="http://g-ecx.images-amazon.com/images/G/31/rcx-events/cat-navs-electronics1._V335880105_.png" alt="Electronics" border="0" height="140" width="170"></a>

    </div>

For this I have tried the following code...

$dom = new DOMDocument();

@$dom->loadHTML($html2);

  foreach($dom->getElementsByClassName("localImage") as $tr) {

$name = '';

foreach($tr->getElementsByTagName('img') as $i)
{
$name = $i->getAttribute('alt');
}
echo $name;

But am getting the following error...

Call to undefined method DOMDocument::getElementsByClassName()

Can anyone please help me where am getting it wrong...as I have tried this code pattern earlier but never faced such issue earlier.

VolkerK
  • 95,432
  • 20
  • 163
  • 226
user3305327
  • 897
  • 4
  • 18
  • 34
  • 3
    Maybe do a bit more research next time. Also that `curl` tag is totally irrelevant to your question. [Get Element by ClassName with DOMdocument() Method](http://stackoverflow.com/questions/20728839/get-element-by-classname-with-domdocument-method) – CollinD Oct 30 '15 at 17:35

2 Answers2

12

Class DOMDocument does not contains method getElementsByClassName
Use xpath

$xpath = new DOMXpath($dom);
$xpath->query('//div[contains(@class, "localImage")]'); //instance of DOMNodeList
cetver
  • 11,279
  • 5
  • 36
  • 56
  • @cetver...thanks for the prompt help, I have not used xpath...so finding it difficult to handle...I am using the following code, @$dom->loadHTML($html2); $xpath = new DOMXpath($dom); $xpath->query('//div[contains(@class, "localImage")]'); $name = ''; foreach($xpath->getElementsByTagName('img') as $i) { $name = $i->getAttribute('alt'); } echo $name; but it gives me error...can you please help me – user3305327 Oct 30 '15 at 17:46
  • with the following code...am getting only [div]...$xpath = new DOMXpath($dom); $elements = $xpath->query('//div[contains(@class, "localImage")]'); foreach ($elements as $element) { echo "
    [". $element->nodeName. "]"; $nodes = $element->childNodes; foreach ($nodes as $node) { echo $node->nodeValue. "\n"; } }
    – user3305327 Oct 30 '15 at 18:06
  • @cetver...can you please help me with the code – user3305327 Oct 30 '15 at 19:00
  • 1
    don't panic ;) Here is the snippet http://ideone.com/L4WK7I – cetver Oct 30 '15 at 20:31
  • That match is not enough. "class" is a token attribute so it can contain any number of classes separated by any number of whitespaces. A simple contains() matches a partial class name, too. – ThW Oct 30 '15 at 23:09
11

The method is not supported by PHPs DOMDocument. It can be emulated by Xpath. Any CSS3 selector that does not return pseudo elements can be converted into an Xpath expression.

So to match a CSS class attribute you have to understand how it works. A CSS class is a token attribute. It contains several class names separated by whitespaces. In Xpath here is a method that can normalize the whitespaces to single spaces. If use that on a class attribute and add a space to the front and back any token matches the pattern {space}ClassOne{space}. With several tokens you would end up with something like {space}ClassOne{space}ClassTwo{space}ClassThree{space}. The important part is that does contain Class but not {space}Class{space}.

The CSS selector .className can be converted into to the Xpath expression .//*[contains(concat(" ", normalize-space(@class), " "), " className ")]. The first part normalizes the attribute so that it matches the token and not just the string that could be part of a token name.

In your case you can refine that to match div elements:

.//div[contains(concat(" ", normalize-space(@class), " "), " localImage ")]

To use Xpath you need to create an DOMXpath instance for the document.

$document = new DOMDocument();
$document->loadHTML($html2);
$xpath = new DOMXpath($document);

$expression = './/div[contains(concat(" ", normalize-space(@class), " "), " localImage ")]';
foreach ($xpath->evaluate($expression) as $div) {
  //...
}
ThW
  • 19,120
  • 3
  • 22
  • 44