I have an issue where I have a div that doesnt have a class or id. Is it possible to select an div element when I know its innerText ie
<div class="thishere"></div>
<div>Search on a this text</div>
If not, the div before it has a class, how do i find its next sibling?
$selector = new Zend_Dom_Query($response->getBody());
$nodes = $selector->query('????');
Using JavaScript you can loop through every element on the page like this says and find that div with the special class. Then, you'll know that the next element in the loop will be that second div and you can get its contents using element.innerHTML.
$text = <<<text
<div class="thishere"></div>
<div>Search on a this text</div>
text;
$selector = new Zend_Dom_Query ($text);
$nodes = $selector->queryXpath('//div[contains(text(),"Search on a this text")]');
foreach ($nodes as $node)
{
...
}
Related
I am getting a code of a page using ob_buffer and i try to replace all divs inside the page that contain the class locked-content.
While it's easy with jquery the problem is that with php is a bit harder. Let say for example i have this html code
<div class='class'> cool content </div>
<div class='class more-class life-is-hard locked-content'>
<div class='cool-div'></div>
<div class='anoter-cool-div'></div>
some more code here
</div>
<div class='class'> cool content </div>
Now it seems like a complex task, I think i need to detect somehow how many divs are open after the div with the class 'locked-content' and then count how many closed div there are and when the wanted div was closed and then replace the code with new code while looping the code in case the div exists more than once.
Anyone has an idea on how to do something like this?
Thanks
You can do it via DOMXPath:
$dom = new DOMDocument();
$dom->loadHtml($html);
$xpath = new DOMXPath($dom);
$node = $xpath->query('//div[contains(#class, "locked-content")]');
foreach ($nodes as $node) {
foreach ($node->childNodes as &$cNode) {
if ($cNode instanceOf DOMElement && $cNode->tagName === 'div') {
$cNode->replaceWith(/* Whatever */);
}
}
}
I want to target a tags with class genre within parent div with id test:
<div id="test">
<a class="genre">hello</a>
<a class="genre">hello2</a>
</div>
So far, I can get all the genre a tags:
$xpath = new DOMXPath($doc);
$elements = $xpath->query('//a[#class="genre"]');
... but I want to adjust //a[#class="genre"] so I only target the ones within the test div.
I don't understand why you did not write it yourself because you use all needed elements of xpath in your expression. Or, maybe, i've misunderstand you question
$elements = $xpath->query('//div[#id="test"]/a[#class="genre"]');
I have a div and I'm trying to insert a couple elements (h3 and p) into the div ahead of the existing h3 and p elements already living inside the div. The PHP documentation for insertBefore (http://www.php.net/manual/en/domnode.insertbefore.php) says this is exactly what should happen, but instead of inserting ahead of the existing elements, its replacing all existing elements inside my 'content' div.
Here's my code:
$webpage = new DOMDocument();
$webpage->loadHTMLFile("news.html");
$headerelement = $webpage->createElement('h3', $posttitle);
$pelement = $webpage->createElement('p', $bodytext);
$webpage->formatOutput = true;
$webpage->getElementById('content')->insertBefore($headerelement);
$webpage->getElementById('content')->insertBefore($pelement);
$webpage->saveHTMLFile("newpost.html");
I'm sure I'm just not understanding something... any help would be appreciated, thanks.
It's because you're not specifying a reference node that the inserted node should be inserted before. Think of it like this:
$whatTheElementIsInsertedInto->insertBefore($theElement, $whatItIsInsertedBefore)
Live demo (click).
$dom = new DOMDocument();
$dom->loadHtml('
<html><head></head>
<body>
<div id="content">
<h3>Original h3</h3>
</div>
</body>
</html>
');
//find the "content" div
$content = $dom->getElementById('content');
//find the first h3 tag in "content"
$origH3 = $content->getElementsByTagName('h3')->item(0);
//create a new h3
$newH3 = $dom->createElement('h3', 'new h3!');
//insert the new h3 before the original h3 of "content"
$content->insertBefore($newH3, $origH3);
echo $dom->saveHTML();
I need to figure the closing tag for below code
<div class="emph"><div class="level"> Some testing </div></div>
In this i need to find the correct tag for parent DIV. my goal is to add the class name before the closing DIV like below
<div class="emph"><div class="level"> Some testing <!--level--></div><!--emph--></div>
For that i need to find the exact closing Parent DIV.
is that possible to achieve in PHP?
You can use simpleXML (or any other XML class) - for each div element, read it's class and append at the end of node content. It's not exactly finding the closing tag, but achieves your specified goal.
Sample code:
$dom = new DOMDocument;
$dom->loadXML($xml);
$divs = $dom->getElementsByTagName('div');
foreach ($divs as $div) {
if ($div->getAttribute('class')!='') {
$div->nodeValue = $div->nodeValue.'<!--'.$div->getAttribute('class').'-->';
}
}
echo $dom->saveXML();
While printing the divs in PHP keep an array $div_array = array()
As soon as you open a div do:
array_push($div_array, 'emph'); // or 'level' depending on the classname
As soon as you're ready to print the closing tag, ask for the value of the last div by:
array_pop($div_array);
// for example
echo '<!-- '.array_pop($div_array).' -->';
Popping the array also deletes the last entry of the array. Which is what you want I presume.
Assume I have a dom_document containing the following html and it is put in a variable called $dom_document
<div>
<a href='something'>some text here</a>
I want this
</div>
What i would like is retrieve the text that is inside the div tag ('I want this'), but not the a tag. What i do is the following:
$dom_document->nodeValue;
Unfortunately with this statement I have the a tag in with it. Hope someone can help. Thank you in advance. Cheers. Marc
You can use XPath for it:
$xpath = new DOMXpath($dom_document);
$textNodes = $xpath->query('//div/text()');
foreach ($textNodes as $txt) {
echo $txt->nodeValue;
}