Finding the parent DIV given an insertion point, in PHP

How do I find the PARENT div in free-form XHTML string, given any insertion point, such as the following

<DIV> <-- this is the DIV I want0>
    <DIV>Not interested in this one</DIV>
    <DIV> Not this one either</DIV>
    <P>Here's my insertion point - I got to start here and work out who my parent DIV is</P>
     <DIV>Not this one either</DIV>
</DIV>

I've been trying to use http://simplehtmldom.sourceforge.net/ but I can't figure out how to use it for this particular operation.

I then tried direct string manipulation, but that was a mess.
metalaureateAsked:
Who is Participating?
 
hieloCommented:
use the parent() method. assuming $e is a reference to the node you just inserted (<P>), then:
$e->parent();

should give you the parent div. You should also be able to chain those method calls to "crawl backwards" up the tree.
$e->parent()->parent();//etc
0
 
level9wizardCommented:
I don't know if its possible, but If you could apply an id or class to that div, it might become a much easier undertaking whichever road you take. You can then use regex to traverse based on that unique id/class string.
0
 
metalaureateAuthor Commented:
Regrettably, all I am given is the insertion point, the rest is an infinite set of varying code.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Adoryc666Commented:
If you are using javascript you can use the method.parentNode on the element.
0
 
level9wizardCommented:
[metalaureate]>>Regrettably, all I am given is the insertion point, the rest is an infinite set of varying code.

Ah, that's too bad. I think your likely going to need some regex here regardless - so you might want to see if you can get this question tagged in there as well.
0
 
metalaureateAuthor Commented:
Hi hielo, my starting point is just an str_pos... but suppose I crawl back to the nearest element (p or div), I then give that a unique ID, then I transform that to a DOM object using simplehtmldom, and THEN get the parent.

Problem then is, what if the nearest element is already the parent DIV? How do I detect that? Otherwise, in this case, I am going to get the grandparent and not know it.
0
 
hieloCommented:
try:
echo $e->parent()->tag;

should give you the name of the tag for the whatever parent() refers to.
0
 
metalaureateAuthor Commented:
To clarify, how to I detect this situation

<DIV>
My insertion point is here.
</DIV>

Maybe, the rule is: go back to nearest element and get its parent, unless you don't encounter any close tag </ on the way back, in which case assume that's the parent.
0
 
hieloCommented:
>>My insertion point is here.
How are you doing this?
0
 
metalaureateAuthor Commented:
Ok, my function gets a string that contains a custom tag, e.g.

<div>
<div></div>
<div></div>
~~#
<div></div>
</div>

What I know is the location of ~~#. I then have to find its parent DIV - none of the elements have meaningful Ids, but there could be any amount of other code surrounding it.

If I crawl back to the nearest element, in this example, that's a div whose parent is INDEED what I want.

However, in this example:

<div
hdfhjsdjsfhsdfs
~~#
</div>

If I crawl back and get that parent's div, I will get the grandparent.

So, in order to detect whether or not the node I crawl back to is already the parent, I thought I could detect the presence of any closing tags "/>", as the absence of a closing tag would indicate that there were no elements between my insertion point and my parent div,

Does that seem right?

Thanks for your help!
0
 
hieloCommented:
I think the "p" block below is basically what you are after.
<?php
include_once('simple_html_dom.php');
$str=<<<HTML
<html><body>
<div id='x'>
<div></div>
<div></div>
<p>~~#</p>
<div></div>
</div>
</body></html>
HTML;

$html=str_get_html($str);
$divSet=$html->find('div');

foreach($divSet as $i=>$div)
{
	if( preg_match('/~~#/',$div->plaintext) )
	{
		echo $div->getAttribute('id');
		echo $div->tag;
	}
}

$pSet=$html->find('p');
foreach($pSet as $i=>$p)
{
	if( preg_match('/~~#/',$p->plaintext) )
	{
		echo $p->tag;
		echo "parent:" . $p->parent()->tag;
	}
}
?>

Open in new window

0
 
metalaureateAuthor Commented:
Let me try that, I'll be back later. Thanks for all your help!
0
 
hieloCommented:
OK
0
 
metalaureateAuthor Commented:
This put me on to the solution. Thank you! All I needed to do was test my original function's output for the presence of my tag (~~#), and it wasn't present, simply recurse parent() until I found it and then take that node.

Thanks!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.