0

I use this code for getting elements of left navigation bar:

function parseInit($url) {
  $ch = curl_init();
  $timeout = 0;
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

$data = parseInit("https://www.smile-dental.de/index.php");
$data = preg_replace('/<(d[ldt])( |>)/smi', '<div data-type="$1"$2', $data);
$data = preg_replace('/<\/d[ldt]>/smi', '</div>', $data);
$html = new simple_html_dom();
$html = $html->load($data);

But faced with such problem.
For example, if I use such syntax for getting elements: $html->find("div[data-type=dd].level2"), then I get ALL elements with data attributes DT, DD, DL and class name LEVEL2. If I use another syntax: $html->find("div.level2[data-type=dd]"), then I get ALL elements with data attribute DD, but with class names LEVEL1, LEVEL2 and LEVEL3 etc.. Could you explain me what the problem is? Thanks in advance!

P.S.: All DT, DL and DD elements was changed with regexp to the DIV elements with appropriate data attributes, because this parser incorrectly counts the number of these elements.

Anoop Asok
  • 1,311
  • 1
  • 8
  • 20
jekahm
  • 149
  • 1
  • 9
  • parsing a DOM is _not_ done using regex, it's done using a DOM parser (`DOMDocument` or `SimpleXMLElement`) they enable you to build, and manipulate a DOM reliably (ie: replacing tags and such) – Elias Van Ootegem Aug 28 '14 at 10:40
  • I told about additional actions (not made by parser) in order to convert some HTML elements. – jekahm Aug 28 '14 at 10:58
  • Yes, all I'm saying is that you really ought to look into alternative approaches: using a different parser, that can handle those tags, for example. Regex + Non-regular languages don't mix, that's just a sad fact of life – Elias Van Ootegem Aug 28 '14 at 11:01

1 Answers1

0

REGEXes are not made to manipulate HTML, DOM parsers are... And simple_html_dom you're using can do it easily...

The following code will do what you want just fine (check comments):

$data = parseInit("https://www.smile-dental.de/index.php");

// Create a DOM object
$html = new simple_html_dom();
$html = $html->load($data);

// Find all tags to replace
$nodes = $html->find('td, dd, dl');

// Loop through every node and make the wanted changes
foreach ($nodes as $key => $node) {
    // Get the original tag's name
    $originalTag = $node->tag;

    // Replace it with the new tag
    $node->tag = 'div';

    // Set a new attribute with the original tag's name
    $node->{'data-type'} = $originalTag;
}
// Clear DOM variable
$html->clear();
unset($html);

Here's is it in action

Now, for multiple attributes filtering, you can use either of the following methods:

foreach ( $html->find("div.level2") as $key => $node) {
    if (  $node->{'data-type'} == 'dt' ) {
        # code...
    }
}

OR (courtesy to h0tw1r3):

// array containing all the filtered nodes
$dts = array_filter($html->find('div.level2'), function($node){return $node->{'data-type'} == 'dt';});

Please read the MANUAL for more details...

Community
  • 1
  • 1
Enissay
  • 4,969
  • 3
  • 29
  • 56
  • Thanks! ) It's much easier than regexp. And it works good in this way. But maybe you know what to do now with query strings, which I've described above and which get wrong result? Would be very grateful for your help! – jekahm Aug 28 '14 at 17:37