0

I'm working with an XML product list that displays a list of around 20 products, and within each <item> there is a <description> and then one <bullet> for each. Here's an example:

XML File with <bullet> List

I'm using a foreach loop with SimpleXML to pull in the product data, and all individual tags such as <image> and <title> are working fine.

My issue is that it is only parsing the first <bullet> for each product and not all of them. To fix this I attempted to add a for loop which targets all nested items within the <description> tag and outputs however many there are. But it's now giving me the first <bullet> of the first item on the XML file and putting it under every product, instead of showing multiple bullets for each respective product, which is what I want.

I'll post my script and hopefully someone will be able to point out where I'm going wrong.

<?php
$items = simplexml_load_file('http://www.itclear.com/BestSellers.xml');

foreach ($items->channel->item as $item):
    $title=$item->title;
    $image=$item->image;
    $price=$item->price;
    $description=$item->description;
    $link=$item->link;

    echo '
             <div class="xsmall-12 medium-6 large-4 columns product">
                <div class="inner">
                    <div class="product-image">
                        <img class="product-image" src="',$image,'"/>
                    </div>
                <h2 class="product-title"><strong>',$title,'</strong></h2>

                <ul>';

    $bullets = $items->channel->item->description;
    for($i=0;$i<=$bullets;$i++){
        echo '<li>',$bullets[$i]->bullet,'</li>';
    }

    echo'
               </ul><span class="product-price">&pound;',$price,'</span>
                <a class="product-link" href="',$link,'" target="_blank" title="Visit ITC Sales to buy ',$title,'">View Deal <i class="fa fa-angle-right" aria-hidden="true"></i></a>
             </div>
         </div>';
    endforeach;

?>

Rendered HTML & CSS

2 Answers 2

1

Your problem is with this line:

$bullets = $items->channel->item->description;

This line has no mention of the elements you're looping over in the outer foreach loop, so has no way to know which item you want to look at. It just says "look at the first <channel> in the document, then look at the first <item> in that, then look at the <description> elements in that".

What you want is to use the $item variable defined in your loop, and look at the <description> elements there:

$bullets = $item->description;

But this variable name is not quite right - the $bullets variable now holds one or more <description> elements, not the <bullet> elements under it. So we should instead say:

$description = $item->description;
$bullets = $description->bullet;

Note that we don't now need $bullets[$i]->bullet, because $bullets[$i] should already be the <bullet> element; you also need to count() the bullets, which is missing in your code. So we have:

for($i=0;$i<=count($bullets);$i++){
    echo '<li>',$bullets[$i],'</li>';
}

To simplify all this, you can just use the same style of foreach loop you already have at the top of the file:

foreach ( $item->description->bullet as $bullet ) {
    echo '<li>',$bullet,'</li>';
}
Sign up to request clarification or add additional context in comments.

1 Comment

For anyone reading this, this works perfectly for me, I'm sure I tried this but I must have done it differently. Thanks IMSoP
0

I also found an alternative solution to this for those also stuck with a similar problem. Here's the code:

    <?php

        $xml = 'http://www.itclear.com/BestSellers.xml';

        $items = simplexml_load_file($xml);

        foreach ($items->channel->item as $item) {

            $title = $item->title;
            $image=$item->image;
            $price=$item->price;
            $description=$item->description;
            $link=$item->link;

            echo '
             <div class="xsmall-12 medium-6 large-4 columns product">
                <div class="inner">
                    <div class="product-image">
                        <img class="product-image" src="',$image,'"/>
                    </div>
                <h2 class="product-title"><strong>',$title,'</strong></h2>

                <ul class="product-description">';

            foreach ($item->description->bullet as $bullet) {
                echo '<li>';
                $b = $bullet;
                echo $b;
                echo "</li>";

            }


            echo'
               </ul><span class="product-price">&pound;',$price,'</span>
                <a class="product-link" href="',$link,'" target="_blank" title="Visit ITC Sales to buy ',$title,'">View Deal <i class="fa fa-angle-right" aria-hidden="true"></i></a>
             </div>
         </div>';

        }

    ?>

1 Comment

This isn't an "alternative" solution, it is exactly what I wrote at the end of my answer. (Except that here you're creating a variable $b with exactly the same value as $bullet for absolutely no reason.)

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.