views:

224

answers:

2

Hi, I've never asked a question here before so please forgive my question if its formatted badly or not specific enough. I am just a dabbler and know very little about PHP and XPath.

I have an XML file like this:

<catalogue>
 <item>
  <reference>A1</reference>
  <title>My title1</title>
 </item>
 <item>
  <reference>A2</reference>
  <title>My title2</title>
 </item>
</catalogue>

I am pulling this file using SimpleXML:

$file = "products.xml";
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");

Then I am using the reference from a URL parameter to get extra details about the 'item' using PHP:

foreach ($xml->item as $item) {
if ($item->reference == $_GET['reference']) {
 echo '<p>' . $item->title . '</p>';
}

So from a URL like www.mysite.com/file.php?reference=A1

I would get this HTML:

<p>My title1</p>

I realise I might not be doing this right and any pointers to improving this are welcome.

My question is, I want to find the next and previous 'item' details. If I know from the URL that reference=A1, how do I find the reference, title etc of the next 'item'? If I only have 'A1' and I know that's a reference node, how do I get HTML like this:

<p>Next item is My title2</p>

I have read about following-sibling but I don't know how to use it. I can only find the following-sibling of the reference node, which isn't what I need.

Any help appreciated.

+2  A: 

You could use:

/catalogue/item[reference='A1']/following-sibling::item[1]/title

Meaning: from an item element child of catalogue root element, having a reference element with 'A1' string value, navegate to first following sibling item element's title child.

Alejandro
Good answer (+1).
Dimitre Novatchev
Thanks for that, it works perfectly.
Hayley
@Hayley Easton: I'm glad it has been helpfull.
Alejandro
A: 

I´d probably use xpath to fetch the next/previous (and current) node.

<?php

error_reporting(E_ALL ^ E_NOTICE);

$s = '
<catalogue>
 <item>
  <reference>A1</reference>
  <title>My title1</title>
 </item>
 <item>
  <reference>A2</reference>
  <title>My title2</title>
 </item>
 <item>
  <reference>A3</reference>
  <title>My title3</title>
 </item>
</catalogue>
';

$xml = simplexml_load_string($s);
$reference = 'A3';

list($current) = $xml->xpath('/catalogue/item[reference="' . $reference . '"]');

if($current) {
    print 'current: ' . $current->title . '<br />';

    list($prev) = $current->xpath('preceding-sibling::*[1]');

    if($prev) {
        print 'prev: ' . $prev->title . '<br />';   
    }

    list($next) = $current->xpath('following-sibling::*[1]');

    if($next) {
        print 'next: ' . $next->title . '<br />';   
    }
}

See the documentation of SimpleXMLElement::xpath and XPath syntax documentation.

Max
Thanks for your answer, this worked for me but I ended up using the first response. I found your solution worked just as well.
Hayley