Search code examples
phphtmlxpathdomdocument

use DOMXPath and function query php


Have the following html code section:

<ul id="tree">
  <li>
    <a href="">first</a>
    <ul>
      <li><a href="">subfirst</a></li>
      <li><a href="">subsecond</a></li>
      <li><a href="">subthird</a></li>
    </ul>
  </li>
  <li>
    <a href="">second</a>
    <ul>
      <li><a href="">subfirst</a></li>
      <li><a href="">subsecond</a></li>
      <li><a href="">subthird</a></li>
    </ul>
  </li>
</ul>

Need parse this html code and get next (using DOMXPath::query() and foreach())

- first
-- subfirst
-- subsecond
-- subthird
- second
-- subfirst
-- subsecond
-- subthird

Piece of code:

$xpath = new \DOMXPath($html);
$catgs = $xpath->query('//*[@id="tree"]/li/a');
foreach ($catgs as $category) {
  // first level
  echo '- ' . mb_strtolower($category->nodeValue) . '<br>';

  // second level
  // don't know
} 

Thanks in advance!


Solution

  • This is what DOMBLAZE is for:

    /* DOMBLAZE */ $doc->registerNodeClass("DOMElement","DOMBLAZE"); class DOMBLAZE extends DOMElement{public function __invoke($expression) {return $this->xpath($expression);} function xpath($expression){$result=(new DOMXPath($this->ownerDocument))->evaluate($expression,$this);return($result instanceof DOMNodeList)?new IteratorIterator($result):$result;}}
    
    $list = $doc->getElementById('tree');
    
    foreach ($list('./li') as $item) {
        echo '- ', $item('string(./a)'), "\n";
        foreach ($item('./ul/li') as $subitem) {
            echo '-- ', $subitem('string(./a)'), "\n";
        }
    }
    

    Output:

    - first
    -- subfirst
    -- subsecond
    -- subthird
    - second
    -- subfirst
    -- subsecond
    -- subthird
    

    DOMBLAZE is FluentDOM for the poor.