Головоломка для синтаксического анализа XML

#php #xml-parsing

#php #xml-синтаксический анализ

Вопрос:

ОБНОВЛЕНИЕ: я переработал вопрос, чтобы показать достигнутый прогресс и, возможно, упростить ответ.

ОБНОВЛЕНИЕ 2: я добавил еще одно значение в XML. Расширение доступно в каждом zip-файле. Каждый элемент может содержать несколько элементов, разделенных табуляцией. Итак, это будет структурировано следующим образом. Платформа> Расширение (подгруппа)> Имя> Заголовок. Если элемент имеет более одного расширения, он будет отображаться в нескольких местах.

У меня есть следующий XML-файл.

 <Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This is the first file group</Title>
    <DownloadPath>/this/windows/1/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This is the first file group</Title>
    <DownloadPath>/this/windows/1/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif</Ext>
    <Name>File Group 1</Name>
    <Title>This is in the same group but has a different title</Title>
    <DownloadPath>/this/windows/1/3.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.</Title>
    <DownloadPath>/this/mac/1/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>jpeg   doc</Ext>
    <Name>File Group 1</Name>
    <Title>This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.</Title>
    <DownloadPath>/this/mac/1/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 2</Name>
    <Title>This is the second file group</Title>
    <DownloadPath>/this/windows/2/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 2</Name>
    <Title>This is the second file group</Title>
    <DownloadPath>/this/windows/2/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 3</Name>
    <Title>This is the second mac file group really.</Title>
    <DownloadPath>/this/windows/3/1.zip</DownloadPath>
</Item>
 

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

 [Windows] => Array (
    [0] => array(
        "Name" => "File Group 1",
        "Title" => "This is the first file group",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/windows/1/2.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 1",
        "Title" => "This has the same name but has a different title, so it should be seperate.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/1/3.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 2",
        "Title" => "This is the second file group",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/2/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/windows/2/2.zip"
            )
        )
    )
),
[Mac] => Array(
    [0] => array(
        "Name" => "File Group 1",
        "Title" => "This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/mac/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/mac/1/2.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 3",
        "Title" => "This is the second mac file group really.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/mac/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/mac/1/2.zip"
            )
        )
    ),
)
 

Вот что у меня получилось с моим php

     $scrape_xml = "files.xml";
    $xml = simplexml_load_file($scrape_xml);

$groups = array();

foreach ($xml->Item as $file){

            if (!isset($groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)])){

                $groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)] = array(
                    'Platform' => $file->Platform,
                    'Name' => $file->Name,
                    'Title' => $file->Title
                );

            }

   $groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)]['Files'][] = $file->DownloadPath;

}

echo "count=" . $i;

echo "<pre>";
print_r($groups);
echo "</pre>";
 

it gives me this result

 Array
(
    [Windows] => Array
        (
            [File Group 1] => Array
                (
                    [This is the first file group] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the first file group
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/2.zip
                                        )

                                )

                        )

                    [This is in the same group but has a different title] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is in the same group but has a different title
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/3.zip
                                        )

                                )

                        )

                )

            [File Group 2] => Array
                (
                    [This is the second file group] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 2
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the second file group
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/2/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/2/2.zip
                                        )

                                )

                        )

                )

        )

    [Mac] => Array
        (
            [File Group 1] => Array
                (
                    [This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Mac
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/mac/1/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/mac/1/2.zip
                                        )

                                )

                        )

                )

            [File Group 3] => Array
                (
                    [This is the second mac file group really.] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Mac
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 3
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the second mac file group really.
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/3/1.zip
                                        )

                                )

                        )

                )

        )

)
 

UPDATE 2: New Array Structure

 [Windows] => Array (
    [gif] =>Array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        )
    ),
    [jpeg] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/2/2.zip"
                )
            )
        )
    ),
    [doc] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 1",
            "Title" => "This has the same name but has a different title, so it should be seperate.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/3.zip"
                )
            )
        ),
        [2] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/2/2.zip"
                )
            )
        )
    )
),
[Mac] => Array(
    [gif] => array(
        [0] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        ),

    )
    [jepg] => array(
        [0] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        )
    )
    [doc] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 3",
            "Title" => "This is the second mac file group really.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/1/2.zip"
                )
            )
        )
    )
)
 

ОБНОВЛЕНИЕ 3: для списка файлов поступает некоторый мусор.

 <Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/1/1.zip</DownloadPath>
    </Item>
    <Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/1/2.zip</DownloadPath>
    </Item>
<Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/2/1.zip</DownloadPath>
    </Item>
    <Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/2/2.zip</DownloadPath>
    </Item>
 

Существует элемент с той же платформой, расширениями, именем и заголовком. Пункты 3 и 4 выше нужно пропустить и сохранить их в массив, с которым я разберусь позже.

Комментарии:

1. что на самом деле вам нужно делать с данными? зачем вы создаете индексы расширений файлов? Я думал, вы просто хотите, чтобы это вводилось в базу данных? Какова ваша желаемая цель здесь — показать путь, который вы прошли до сих пор, чтобы скрыть цель…

2. Ян, ты прав. Я скрываю, что я делаю. В основном, чтобы все было просто. Тот факт, что у меня есть 7 совершенно хороших ответов ниже, доказывает, что это не оказывает плохого эффекта. Извините, если это вас раздражает.

3. Это не раздражает — просто похоже, что вы, возможно, получаете не самые лучшие ответы, особенно при редактировании OP.

4. чтобы быть хорошим, возможно, было бы лучше иметь тег <extensions> с <ext>gif</ext><ext>jpg</ext> — наличие большего количества атомарных данных должно «помочь».

Ответ №1:

Вы просто отображаете входные значения в выходной массив, упорядочивая их по-разному, это ваша структура:

 Array(
  [... Item/Platform] => Array (
    [... Item/Title as 0-n] => array(
        "Name" => Item/Name,
        "Title" => Item/Title,
        "Files" => array(
            [...] => array(
                "DownloadPath" => Item/DownloadPath
            ),
        )
    ),
 

Сопоставление может быть выполнено путем перебора элементов в XML и сохранения значений в соответствующем месте в новом массиве (я назвал его $build ):

 $build = array();
foreach($items as $item)
{
    $platform = (string) $item->Platform;
    $title = (string) $item->Title;
    isset($build[$platform][$title]) ?: $build[$platform][$title] = array(
        'Name' => (string) $item->Name,
        'Title' => $title
    );
    $build[$platform][$title]['Files'][] = array('DownloadPath' => (string) $item->DownloadPath);
}
$build = array_map('array_values', $build);
 

array_map Вызов выполняется в конце для преобразования Item/Title ключей в числовые.

И это все, вот демонстрация.

Дайте мне знать, если это будет полезно.

Редактировать: для ваших обновленных данных это небольшая модификация приведенного выше, ключевые принципы предыдущего примера все еще существуют, дополнительно устранено дополнительное дублирование для каждого дополнительного расширения для каждого элемента, путем добавления еще одной итерации внутри:

 $build = array();
foreach($items as $item)
{
    $platform = (string) $item->Platform;
    $title = (string) $item->Title;
    foreach(preg_split("~s ~", $item->Ext) as $ext)
    {
        isset($build[$platform][$ext][$title])
            ?:$build[$platform][$ext][$title] = array(
                'Name' => (string) $item->Name,
                'Title' => $title
            );
        $build[$platform][$ext][$title]['Files'][]
            = array('DownloadPath' => (string) $item->DownloadPath);
    }
}
$build = array_map(function($v) {return array_map('array_values', $v);}, $build);
 

Комментарии:

1. если бы я добавил туда еще один уровень, т.Е. Платформа> расширение> имя> заголовок. Как это будет работать?

2. Конечно, я думаю, вы хотите сгруппировать / подгруппировать платформу с расширением. Это возможно, это просто дополнительное смещение между $platform и $title . Если вы не хотите группировать, вы можете создать комбинированный ключ с "$platform$extension" помощью .

3. Спасибо. Просто замечаю это сейчас. Элемент расширения имеет несколько выходных данных, разделенных табуляцией. Если элемент имеет более одного расширения, его следует добавить в каждую группу расширений. Я думаю, что итерация не собирается сокращать ее для этого.

4. конечно, вам нужно добавить один и тот же элемент только один раз для каждого расширения. Однако вы уверены, что хотите дублировать данные таким образом? Кроме того, почему бы вам не добавить фактические элементы расширения вместо одного с неоднозначным значением символа? Что-то вроде <exts><ext>JPG</ext><ext>GIF</ext></exts> — Это делает его еще более простым.

5. это то, с чем мне приходится иметь дело, я боюсь. Я хочу добавить элемент один раз для каждого расширения, но дублировать элементы. Кроме того, возникли трудности с добавлением дополнительного смещения. Это нарушает структуру массива.

Ответ №2:

начните с объявления

 $groups[stripslashes($file->Platform)][stripslashes($file->Name)]
  [stripslashes($file->Title)] = (object)array(
    'Name' => $file->Name,
    'Title' => $file->Title,
    'Files' = (object)array()
  );
 

Это поможет вам приблизиться.

Вы также должны проверять тип каждого элемента XmlElement по мере его получения, чтобы увидеть, является ли он массивом или простым объектом. Затем обработайте соответствующим образом.

Ответ №3:

Вы не объяснили, что именно вы видите неправильно, поэтому мне придется догадаться.

Во-первых, в вашем исходном коде ваш последний путь /this/windows/3/1.zip загрузки указан, хотя я уверен, что это должен быть файл Mac — mis-type, но вывод будет «выглядеть неправильно» с этим.

Далее, если вам нужны строки, а не объекты SimpleXMLElement, вам нужно это (также была сделана некоторая уборка, чтобы избежать большого количества stripslashes() вызовов):

 foreach ($xml->Item as $file) {
    $platform = stripslashes((string) $file->Platform);
    $name = stripslashes((string) $file->Name);
    $title = stripslashes((string) $file->Title);
    if( !isset($groups[$platform][$name][$title])) {
        $groups[$platform][$name][$title] = array(
            'Platform' => $platform,
            'Name' => $name,
            'Title' => $title 
        );
    } 
    $groups[$platform][$name][$title]['Files'][] = (string) $file->DownloadPath;
}
 

Обратите внимание на (string) биты? Они преобразуют объект в строку, что позволяет вам получить доступ к буквальному значению, а не к объекту. Это также причина, по которой ваши ключи массива работали, потому что они были внутренне преобразованы в строки (в качестве ключей массива могут использоваться только строки и целые числа).

Я думаю, что это все, что я могу найти, что может ответить на ваш вопрос. Если это не так, пожалуйста, дайте мне знать более четко, что не так, и я буду рад попытаться помочь.

Ответ №4:

Я сам предпочитаю DOM DOcument и XPath, поэтому я бы сделал его…

 $xml = 'pathtoyourfile.xml';
$doc = new DOMDocument( '1.0', 'UTF-8' );
$doc->load( $xml );

$dxpath = new DOMXPath( $doc );
$items = $dxpath->query( '//Item' );

$db = new PDO( 'mysql:dbname=YOURDB:host=YOURHOST', $DBUSER, $DBPASS );
$ins = $db->prepare('
                    INSERT INTO ur_table
                    ( `platform` , `name` , `title` , `path` )
                    VALUES
                    ( :platform , :name , :title , :path );
                    ');

foreach( $items as $item )
{
    $ins->bindValue( ':platform'     , $item->getElementsByTagName( 'PlatForm' )->item(0)->nodeValue , PDO::PARAM_STR );
    $ins->bindValue( ':name'         , $item->getElementsByTagName( 'Name' )->item(0)->nodeValue     , PDO::PARAM_STR );
    $ins->bindValue( ':title'        , $item->getElementsByTagName( 'Title' )->item(0)->nodeValue    , PDO::PARAM_STR );
    $ins->bindValue( ':DownloadPath' , $item->getElementsByTagName( 'PlatForm' )->item(0)->nodeValue , PDO::PARAM_STR );
    $ins->execute();
}
 

Нет необходимости в полосовых косых чертах, а что нет — он обработает все за вас.

Ответ №5:

Как что-то подобное? Код немного неаккуратный, и, вероятно, следует внести изменения для улучшения проверки.

 class XMLFileImporter {
  public $file; //Absolute path to import file
  public $import = array();
  public $xml;
  public $error = false;

  public function __construct($file) {
    $this->file = $file;
    $this->load();
  }

  public function load() {
    if(!is_readable($this->file)) {
      $this->error("File is not readable");
      return false;
    }

    $xml = simplexml_load_file($this->file);
    if(!$xml) {
      $this->error("XML could not be parsed");
      return false;
    }
    $this->xml = json_decode(json_encode($xml));

    return true;
  }

  public function import() {
    $count = $this->parseItems();
    echo "Imported $count rows";

  }

  public function parseItems() {
    if($this->error()){
      return false;
    }

    if(!self::validateXML($this->xml)) {
      $this->error("Invalid SimpleXML object");
      return false;
    }

    if(!self::validateArray($this->xml->Item)) {
      $this->error("Invalid Array 'Item' on SimpleXML object");
      return false;
    }
    $count = 0;
    foreach($this->xml->Item as $item) {
      if($this->parseItem($item)){
        $count  ;
      }
    }
    return $count;

  }
  public function parseItem($item) {
    if($this->error()){
      return false;
    }

    if(!self::validateItem($item)) {
      $this->error("Invalid file item");
      return false;
    }

    $item = self::normalizeItem($item);

    $this->handlePlatform((string)$item->Platform);
    $this->handleGroup($item);
    $this->handleSubGroup($item);
    $this->handleFile($item);
    return true;
  }

  public function handlePlatform($platform) {
    if(!isset($this->import[$platform])) {
      $this->import[$platform] = array();
    }

    return true;
  }

  public function handleGroup($item) {
    if(!isset($this->import[$item->Platform][$item->Name])) {
      $this->import[$item->Platform][$item->Name] = array();
    }
    return true;
  }

  public function handleSubGroup($item) {
    if(!isset($this->import[$item->Platform][$item->Name][$item->Title])) {
      $this->import[$item->Platform][$item->Name][$item->Title] = array();
    }
    return true;
  }

  public function handleFile($item) {
    array_push($this->import[$item->Platform][$item->Name][$item->Title],$item->DownloadPath);
  }

  public function error($set=false) {
    if($set){
      $this->error = $set;
      return true;
    }
    return $this->error;
  }

  public static function validateXML($xml) {
    return is_object($xml);
  }
  public static function validateArray($arr,$min=1){
    return (isset($arr) amp;amp; !empty($arr) amp;amp; count($arr) > $min);

  }

  public static function validateItem($item){
    return (isset($item->Title)
           amp;amp; isset($item->Name)
           amp;amp; isset($item->DownloadPath)
           amp;amp; isset($item->Platform));

  }

  public static function normalizeItem($item){
    $item->Name = stripslashes(trim((string)$item->Name));
    $item->Title = stripslashes(trim((string)$item->Title));
    $item->Platform = (string)$item->Platform;
    $item->DownloadPath = (string)$item->DownloadPath;

    return $item;
  }

  public function output() {
    print_r($this->import);
    return true;
  }

}

$importer = new XMLFileImporter(dirname(__FILE__)."/files.xml");
$importer->load();
$importer->import();
$importer->output();
var_dump($importer->error());
 

Ответ №6:

Вы можете попробовать это:

 $scrape_xml = "files.xml";
$xml = simplexml_load_file($scrape_xml);

$group = array();

foreach ($xml->Item as $file)
{
    $platform = stripslashes($file->Platform);
    $name = stripslashes($file->Name);
    $title = stripslashes($file->Title);
    $downloadPath = stripslashes($file->DownloadPath);

    if(!isset($group[$platform]))
    {
        $group[$platform] = array();
        $group[$platform][] = array("Name" => $name,"Title" => $title, "Files" => array($downloadPath));
    }
    else
    {
        $found = false;

        for($i=0;$i<count($group[$platform]);$i  )
        {
            if($group[$platform][$i]["Name"] == $name  amp;amp; $group[$platform][$i]["Title"] == $title)
            {
                $group[$platform][$i]["Files"][] = $downloadPath;
                $found = true;
                break;
            }
        }

        if(!$found)
        {
            $group[$platform][] = array("Name" => $name,"Title" => $title, "Files" => array($downloadPath));
        }
    }
}

echo "<pre>".print_r($group,true)."</pre>";
 

Ответ №7:

Это код, который даст вам нужный результат. ОБНОВЛЕНИЕ: это касается последней запрошенной вами группировки.

 $scrape_xml = "files.xml";
$xml = simplexml_load_file($scrape_xml);
$groups = array();

foreach ($xml->Item as $file){
    $platform = stripslashes($file->Platform);
    $name = stripslashes($file->Name);
    $title = stripslashes($file->Title);
    $extensions = explode('    ', $file->Ext);

    foreach($extensions as $extension)
    {
        if (!isset($groups2[$platform])) $groups2[$platform] = array();
        if (!isset($groups2[$platform][$extension])) $groups2[$platform][$extension] = array();

        $groupFound = false;
        for($idx = 0; $idx < count($groups2[$platform][$extension]); $idx   ) {
            if ($groups2[$platform][$extension][$idx]["Name"] == $name 
                amp;amp; $groups2[$platform][$extension][$idx]["Title"] == $title) {

                $groups2[$platform][$extension][$idx]["Files"][] =
                    array('DownloadPath' => $file->DownloadPath."");

                $groupFound = true;

                break;
            }
        }

        if ($groupFound) continue;

        $groups2[$platform][$extension][] = 
            array(
                "Name" => $name,
                "Title" => $title,
                "Files" => array(array('DownloadPath' => $file->DownloadPath."")));
    }
}

echo "<br />";
echo "<pre>";
print_r($groups2);
echo "</pre>";
 

Комментарии:

1. Если бы я хотел добавить туда еще одну группировку / элемент. платформа ie> расширение> имя> заголовок это было бы легко изменить?

2. Я обновил свой пост, чтобы отразить ваши изменения в отношении группировки.