PHP SimpleXML Группировка по типу элемента - PullRequest
2 голосов
/ 31 июля 2009

Хорошо, вот моя дилемма. Я ищу способ консолидации данных в группе, используя SimpleXML в PHP . Вот что я имею в виду.

Допустим, у меня есть XML, который выглядит следующим образом:

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

Вот что я хочу, чтобы выглядело так:

Видео

  • Казино Рояль - Джеймс Бонд Борн
  • Идентификация Борна - Джейсон Борн

Книга

  • Шантарам - Линдсей Форд

Пожалуйста, помогите мне! Дайте мне знать, если что-то сбивает с толку.

Ответы [ 2 ]

4 голосов
/ 31 июля 2009

Если вы заранее не знаете типы фильмов, вы можете:

  • извлечение всех типов из данных XML
    • получите их как уникальные, так как они могут появляться несколько раз (возможно, есть способ сделать это с XPath; я не знаю этого, поэтому я буду использовать array_unique)
  • переберите эти типы, используя то, что @ Марк предложил .


Что-то вроде этого, вероятно, подойдет:

$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 ;-)

}


И чтобы было легче понять, вот выходные данные var_dump:

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)


Теперь вам нужно представить эти данные так, как вы хотите; цикл с двойным циклом, создающий теги <ul> и <li>, вероятно, будет делать ; -)

1 голос
/ 31 июля 2009

Я думаю, вы ищете Xpath:

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

Затем вы можете циклически перебирать $ arrMovies и $ arrBooks и распечатывать то, что вам нужно:

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