Extract HTML data using php/DOM - php

Im newbie with DOM so can someone tell me how to parse the following in php?
<div class="classname1">
<div class="description">some description</div>
<div class="classname2">
<div class="classname3">some text 1</div>
<div class="classname4">some text 2</div>
<div class="classname6">some text 4</div>
</div>
</div>
I would like to retrieve the text in the above class. There could be mode div before and after the html mentioned. I know I should create a dom
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$divs = $xpath->query('//div[#class="classname1"]');
foreach ($divs as $div) {
//...
}
I dont know how to access the classnames data

you can use the getAttribute on the DOMElement
http://www.php.net/manual/en/domelement.getattribute.php

Related

PHP: "Couldn't fetch DOMElement. Node no longer exists in" using DOMXpath

I have some HTML that contains this:
<div class="test">
Outer
<div class="test">Inner 1</div>
<div class="test">Inner 2</div>
</div>
I'm doing str_replace() on the contents of these elements:
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);
foreach($xpath->query("//div[#class='test']") as $node) {
$node->nodeValue = str_replace(" ", "X", $node->nodeValue);
}
That should replace any spaces with an "X".
But it results in this error:
Warning: Couldn't fetch DOMElement. Node no longer exists in /path/to/my/file.php on line 63
It works if there's only one nested div:
<div class="test">
Outer
<div class="test">Inner 1</div>
</div>
Why does this happen, and how can I get it working?
Try changing
foreach($xpath->query("//div[#class='test']") as $node)
to
foreach($xpath->query('//div[#class="test"]//div[#class="test"]') as $node)
Edit per comments:
Assuming there's a space in the outer element (i.e., its "Outer 1:):
<?php
$string = <<<XML
<div class="test">
Outer 1
<div class="test">Inner 1</div>
<div class="test">Inner 2</div>
</div>
XML;
$dom = new DOMDocument();
$dom->loadHTML($string);
$xpath = new DOMXpath($dom);
foreach($xpath->query('//div[#class="test"]//text()') as $node) {
$nnode = trim($node->nodeValue);
echo $nnode = str_replace(" ", "X", $nnode);
}

Extracting value of a node after a certain tag

Tying to extract the value "Output" between spans only if the title is "ABCD (1,2)" using php. Basically, find "Output (extract Output).
Here is the section of html:
<div class="wrap">
<strong title="ABCD (1,2)" class="name">ABCD (1,2):</strong>
<div id="test1">
<div class="testclass" id="test2">
<span>Output</span>
</div>
</div>
</div>
Here is the code I like to use:
<?php
$html = file_get_contents('test.html');
$dom = new DOMDocument;
#$dom->loadHTML($html);
//Some code needs to go here!
$tags = $dom->getElementsByTagName('strong');
?>
One way would be to just use xpath in this case, use a query that would select that desired element. Get that element that has that title and get the following div, and under it, go to the span:
Example (using the markup above):
$html = '
<div class="wrap">
<strong title="ABCD (1,2)" class="name">ABCD (1,2):</strong>
<div id="test1">
<div class="testclass" id="test2">
<span>Output</span>
</div>
</div>
</div>
';
$search_string = 'ABCD (1,2)';
$dom = new DOMDocument;
#$dom->loadHTML($html);
$query = "//strong[#title = '{$search_string}']/following-sibling::div/div/span";
$xpath = new DOMXpath($dom);
$result = $xpath->query($query);
if($result->length > 0) {
echo $result->item(0)->nodeValue;
}

Get all html data in a tag parent with id or class use php

I have the following text:
<div id="parent">
<div class="box1"> content 1</div>
<div class="box2"> content 1</div>
<div class="box3"> content 1 <div class="box31"></div></div>
</div>
What I've tried:
preg_match_all ("/<div id=\"parent\">([^`]*?)<\/div>/", $str_test, $matches);
print_r($matches);exit;
I want to get all the content:
<div class="box1"> content 1</div>
<div class="box2"> content 1</div>
<div class="box3"> content 1 <div class="box31"></div></div>
It is not working and I need help.
You shouldn't parse HTML with regex. You can and you should do that with DOMDocument.
$string = '<div id="parent">
<div class="box1"> content 1</div>
<div class="box2"> content 1</div>
<div class="box3"> content 1 <div class="box31"></div></div>
</div>';
$dom = new DOMDocument();
$dom->loadHTML($string);
$xpath = new DOMXPath($dom);
$parentNode = $xpath->query("//div[#id='parent']");
$html = '';
foreach ($parentNode->item(0)->childNodes as $node) {
$html .= $node->ownerDocument->saveHtml($node);
}
echo $html;
The saveHTML method allows you to get the whole html from each node of the node parent (<div id="parent">).
Demo.
If you really need to use regex, perhaps as a general text parsing not limited to well-formed HTML, then you should:
Use preg_match instead of preg_match_all
Lose the ? in your pattern.
Your desired result should be inside $matches[1].

DOMXPath to find specific image tag

My question is very direct. Here is my html dom,
<html>
...
<div class="A B">
<div class="C">
<img src="..." >
</div>
<div>
...
<div class="A">
</div>
...
</html>
Now I want to get the image's src in div[class="A B"]-><div class="C">-><img> using DOMXPath in php code.
The main puzzle is that I do not know how to write it's path correctly.
Update
I have tried How to get data from HTML using regex, but it doesn't work still.
The actual html structure is :
My php code:
$doc = new DOMDocument();
$doc->loadHTML($html);
$title = $doc->getElementsByTagName('title')->item(0)->nodeValue;
$XPath = new DOMXPath($doc);
$vipImg = $XPath->query('//div[#class="show-midpic active-pannel"]/a/div[#class="zoomPad"]/img');
var_dump($vipImg);
foreach($vipImg as $vip)
{
var_dump($vip);
}
And the output is :
object(DOMNodeList)#2 (1) { ["length"]=> int(0) }

Retrieve a text node with Simple HTML DOM Parser

I'm quite new to Simple HTML DOM Parser. I want to get a child element from the following HTML:
<div class="article">
<div style="text-align:justify">
<img src="image.jpg" title="image">
<br>
<br>
"Text to grab"
<div>......</div>
<br></br>
................
................
</div>
</div>
I'm trying to get the text "Text to grab"
So far I've tried the following query:
$html->find('div[class=article] div')->children(3);
But it's not working. Any idea how to solve this ?
You don't need simple_html_dom here. It can be done with DOMDocument and DOMXPath. Both are part of the PHP core.
Example:
// your sample data
$html = <<<EOF
<div class="article">
<div style="text-align:justify">
<img src="image.jpg" title="image">
<br>
<br>
"Text to grab"
<div>......</div>
<br></br>
................
................
</div>
</div>
EOF;
// create a document from the above snippet
// if you are loading from a remote url use:
// $doc->load($url);
$doc = new DOMDocument();
$doc->loadHTML($html);
// initialize a XPath selector
$selector = new DOMXPath($doc);
// get the text node (also text elements in xml/html are nodes
$query = '//div[#class="article"]/div/br[2]/following-sibling::text()[1]';
$textToGrab = $selector->query($query)->item(0);
// remove newlines on start and end using trim() and output the text
echo trim($textToGrab->nodeValue);
Output:
"Text to grab"
If it's always in the same place you can do:
$html->find('.article text', 4);

Categories