0

I am loading external HTML content into a variable like this:

$content = file_get_contents('http://localhost');

The page has a set of loops of <ul> like this:

<ul class="items-list">
<li>Title1</li>
<li>Description1</li>
<li>Location1</li>
</ul>
<!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
<a href="#">
<div class="item-price">£10</div>
<a/>

<ul class="items-list">
<li>Title2</li>
<li>Description2</li>
<li>Location2</li>
</ul>
<!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
<a href="#">
<div class="item-price">£15</div>
</a>

<ul class="items-list">
<li>Title3</li>
<li>Description3</li>
<li>Location3</li>
</ul>
<!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
<a href="#">
<div class="item-price">£20</div>
</a>

<ul class="items-list">
<li>Title4</li>
<li>Description4</li>
<li>Location4</li>
</ul>
<!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
<a href="#">
<div class="item-price">£25</div>
</a>

I have the following code that uses DOMXPath to search for all the items-list UL's and then I can loop through it and echo it.

$dom = new DomDocument();
$dom->loadHTML($content);
$xpath = new DOMXPath($dom); 
$items = $xpath->query("//ul[@class='items-list']"); 

foreach ($items as $node) { 
  echo $node->textContent;
}

This work's perfectly. However, I need help displaying the price of each one of these loops which comes from the div class called item-price which is after the UL but not immediately after.

How can I do this?

0

3 Answers 3

1
foreach ($items as $node) { 
  echo $node->textContent;
  $div = $xpath->query('.//following::div[@class="item-price"][1]', $node); 
  echo $div[0]->nodeValue ."\n\n";
}

demo

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, that seems to work howevever, the price seems to be coming with extra symbol like this: £25
Just write $dom->loadHTML(utf8_decode($content));
0

Use the following-sibling axis

$xpath->query("//ul[@class='items-list']/following-sibling::div[@class='item-price']"); 

1 Comment

This doesn't seem to work. returns completely empty with no results.
0

Using the original query combined with a following-sibling operator perhaps will suffice.

define('BR','<br />');

$strhtml='<ul class="items-list">
    <li>Title1</li>
    <li>Description1</li>
    <li>Location1</li>
    </ul>
    <!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
    <div class="item-price">£10</div>

    <ul class="items-list">
    <li>Title2</li>
    <li>Description2</li>
    <li>Location2</li>
    </ul>
    <!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
    <div class="item-price">£15</div>

    <ul class="items-list">
    <li>Title3</li>
    <li>Description3</li>
    <li>Location3</li>
    </ul>
    <!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
    <div class="item-price">£20</div>

    <ul class="items-list">
    <li>Title4</li>
    <li>Description4</li>
    <li>Location4</li>
    </ul>
    <!-- OTHER CONTENT HERE BETWEEN THE UL AND THE PRICE DIV -->
    <div class="item-price">£25</div>';


    $dom = new DomDocument();
    $dom->loadHTML( $strhtml );
    $xpath = new DOMXPath( $dom ); 
    $items = $xpath->query("//ul[@class='items-list'] | //ul[@class='items-list']/following-sibling::div[@class='item-price']"); 
    if( $items && $items->length > 0 ){
        foreach ( $items as $node ) { 
            echo $node->textContent . BR;
        }
    }

The above outputs

Title1 Description1 Location1 
£10
Title2 Description2 Location2 
£15
Title3 Description3 Location3 
£20
Title4 Description4 Location4 
£25

Given the change to the html content a minor modification to the XPath query is required as the div containing the prices is no longer a direct sibling - though it could be.

$items = $xpath->query("//ul[@class='items-list'] | //ul[@class='items-list']/following::div[@class='item-price']");

5 Comments

Doesn't seem to be working, is it supposed to be in the same $node->textContent ?I tried print_r($node->textContent); [nextSibling] => (object value omitted)
ah - remove BR ~ that is a constant define('BR','<br />'); - might be the reason
Thanks RamRaider, but it appears that the <div class="item-price">£10</div> is inside a <a href> so it actually looks like this <a href=""><div class="item-price">£10</div></a> And because of this a href it does'nt work. Is there a way around this?
if I remove the a tags then it works, but with the A tags it doesnt work. I need it to work with the A tags. any ideas?
can you update your question to reflect the actual data

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.