3

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 Answers 2

3

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.

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

1 Comment

@Hayley Easton: I'm glad it has been helpfull.
2

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.

1 Comment

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

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.