5

I am trying to select a (direct) child of parents div.element using the > combinator, but it's failing.

HTML:

<div class="element">
    <p>test</p>
</div>

<div class="element">
    <div class="selected">
        <p>test2</p>
    </div>
</div>

PHP:

$html->find('div.element > p', 0);

I am looking to select the direct p element.

If it's a nested descendant - it shouldn't return anything, but it returns test2.

How can I write it to return test, but not test2? Thanks

UPDATE: The general consensus here on SO seems to be that Simple HTML DOM is bad. I ended up writing my code using PHP's DOMDocument as suggested by Phil. I did test out nevermind's solution and it did work as well. Thanks for all the help and Happy Coding

Leo
  • 10,407
  • 3
  • 45
  • 62
RisingSun
  • 1,693
  • 27
  • 45
  • try to delete the angle bracket – aldrin27 Aug 13 '15 at 00:16
  • 1
    **test2** is returned either way. `>` seems to do nothing – RisingSun Aug 13 '15 at 00:18
  • 1
    Try this: $html->find(div.element > p); – aldrin27 Aug 13 '15 at 00:20
  • @aldrin27 that at least changed behavior. On the second element, it seems to return an empty string. I though it returned null if the element wasn't found. Also, specifying element index in the find call makes it look deeper? – RisingSun Aug 13 '15 at 00:25
  • 3
    SimpleHTMLDom is a truly terrible library and I doubt it supports the immediate child selector. See this page for a list of **much better** alternatives ~ http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php – Phil Aug 13 '15 at 00:27
  • @Phil I would love to just drop this thing and move on to another but it is not up to me and there already is a lot of code written using this. My only option is to try and work with what I have already. – RisingSun Aug 13 '15 at 00:29
  • FYI, this XPath expression will yield the result you're after ~ `//div[@class = 'element']/p` – Phil Aug 13 '15 at 00:30
  • 1
    @khuderm you can use something else for this task (I recommend the built-in Dom extension). It doesn't mean you need to drop SimpleHTMLDom or refactor any other code – Phil Aug 13 '15 at 00:32
  • @Phil You are right. I wasted too much time trying to make this work. I wrote only this part using php `DOMDocument` and that was like a breeze. If you wanna make your comment an answer, I will accept it. I try to stay away from xpath, personally. They tend to break easily with the smallest structure change. – RisingSun Aug 13 '15 at 00:51
  • 1
    For a simple html dom replacement with full css support [try this](https://github.com/monkeysuffrage/advanced_html_dom). Yes simple html dom is bad but it's also a very old library and for a while it was all we had. – pguardiario Aug 13 '15 at 23:36

1 Answers1

2

Well, this should (must, actually:)) work (tested on 4 divs):

foreach($html->find('div.element') as $element) {


$paragraph=$element->find('p',0);

    if($paragraph==$element->first_child())
    echo $paragraph;

}
sinisake
  • 11,240
  • 2
  • 19
  • 27
  • I did test out your code after I found my solution. Not sure why you deleted your answer in the first place lol. I ended up doing what @Phil suggested. If he doesn't write an answer, I will choose your as a solution since it works as well. Thanks – RisingSun Aug 13 '15 at 01:02
  • Np, first solution didn't worked for two

    adjacent tags (if it is possible in your HTML structure) - IF you just want first... :)

    – sinisake Aug 13 '15 at 01:04
  • That would have worked in my case. The first element with just the span is sometimes there and sometimes not. If it was there, I needed the value inside it only. If it didn't I wanted the value from the second element. Anyway, thank you very much for your help! – RisingSun Aug 13 '15 at 01:09