2

Ok here's my dilemma. I am looking for a way to consolidate the data in a group using SimpleXML in PHP. Here's what I mean.

Let's say I have an xml that looks like this:

  <favorites>
    <interesting>
        <type>Movie</type>
        <character>James Bond</character>
        <name>Casino Royale</name>
    </interesting>
    <interesting>
        <type>Movie</type>
        <character>Jason Bourne</character>
        <name>Bourne Identity</name>
    </interesting>
    <interesting>
        <type>Book</type>
        <character>Lindsay Ford</character>
        <name>Shantaram</name>
    </interesting>
  </favorites>

Now here's what I want that to look like:

Movie

  • Casino Royale - James Bond Bourne
  • Bourne Identity - Jason Bourne

Book

  • Shantaram - Lindsay Ford

Please help me!! Let me know if anything is confusing.

3
  • Thanks Mark. I forgot to mention that there is huge list of "types" and I don't want to write xpath for each one, is there a way to automatically find "types" instead of hard coding the values (eg. "Movie", "Book")? Commented Jul 30, 2009 at 21:46
  • $arrTypes = $xml->xpath('interesting/type'); will give you all of the types. Unfortunately it will be an array of simplexml objects. You'll need to loop over it and put all of the types into a new array, and then array_unique() the new array. Commented Jul 30, 2009 at 21:55
  • Can you help me out on this a little more? I am a n00b. :( Thanks man! Commented Jul 30, 2009 at 21:58

2 Answers 2

4

If you don't know in advance the types of movies, you could :

  • extract all types from the XML data
    • get them as unique, as they may appear several times (There might be a way to do that with XPath ; I don't know it, so I'll use array_unique)
  • iterate over these types, using what @Mark proposed.


Something like this would probably do :

$xml = simplexml_load_string($xmlData);

$typesListXml = $xml->xpath('interesting/type');
var_dump($typesListXml);    // var_dump #1

if (!empty($typesListXml)) {
    $typesList = array();
    foreach ($typesListXml as $typeXml) {
        $typesList[] = (string)$typeXml;
    }
    var_dump($typesList);    // var_dump #2

    $typesList = array_unique($typesList);
    var_dump($typesList); // var_dump #3

    $moviesForType = array();
    foreach ($typesList as $type) {
        $rawData = $xml->xpath('interesting[type="' . $type . '"]');
        if (!empty($rawData)) {
            foreach ($rawData as $rawMovie) {
                $moviesForType[$type][] = $rawMovie->name . ' - ' . $rawMovie->character;
            }
        }
    }

    var_dump($moviesForType); // var_dump #4

    // Up to you to present $moviesForType the way you want ;-)

}


And to make things easier to understand, here are the var_dump's outputs :

var_dump #1 :

array
  0 => 
    object(SimpleXMLElement)[2]
      string 'Movie' (length=5)
  1 => 
    object(SimpleXMLElement)[3]
      string 'Movie' (length=5)
  2 => 
    object(SimpleXMLElement)[4]
      string 'Book' (length=4)

var_dump #2 :

array
  0 => string 'Movie' (length=5)
  1 => string 'Movie' (length=5)
  2 => string 'Book' (length=4)

var_dump #3 :

array
  0 => string 'Movie' (length=5)
  2 => string 'Book' (length=4)

var_dump #3 :

array
  'Movie' => 
    array
      0 => string 'Casino Royale - James Bond' (length=26)
      1 => string 'Bourne Identity - Jason Bourne' (length=30)
  'Book' => 
    array
      0 => string 'Shantaram - Lindsay Ford' (length=24)


Now, it's up to you to present those data the way you want ; a double-foreach loop constructing <ul> and <li> tags would probably do ;-)

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

Comments

1

I believe you are looking for Xpath:

$xmlData = '<favorites>...</favorites>';
$xml = simplexml_load_string($xmlData);
$arrMovies = $xml->xpath('interesting[type="Movie"]');
$arrBooks = $xml->xpath('interesting[type="Book"]');

You can then loop over $arrMovies and $arrBooks and print out what you need:

foreach($arrMovies as $movie) {
    echo $movie->name;
}

Comments

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.