Как сохранить данные из XML файла в базу данных MySQL разделяя на категории?

209
18 июля 2019, 14:40

Получаю данные из XML файла и сохраняю в базу данных.

$read = simplexml_load_file($file); // получаем объект класса
$xml = $read->Category->Site; // $xml - объект-массив, вложенные теги - его свойства
$count = count($xml); // кол-во элементов массива
for($i = 0; $i < $count; $i++){
$date_xml = mysql_real_escape_string($xml[$i]->Id);
$title_xml = mysql_real_escape_string($xml[$i]->Title);
$id_xml = mysql_real_escape_string($xml[$i]->Description);
$values .= "('$id_xml', '$date_xml','$title_xml','$link_xml'),";
/* заносим данные в БД если накопилось 1000 записей при подготовке запроса*/
if($i % 1000 == 0)
{
$values[strlen($values)-1]=' ';
$res = mysql_query("$Query $values $ODKU");
$values = "";
}
}

if(strlen($values)>0)
{
$values[strlen($values)-1]=' ';
/* заносим данные в БД */
$res = mysql_query("$Query $values $ODKU");    
}
echo 'Done';

Файл XML имеет следующий вид

<?xml version="1.0" encoding="UTF-8"?>
<Catalog>
<Category>
<Name>CAT 1</Name>
<Site>
<Id>ID 1</Id>
<PopularityRank>1</PopularityRank>
<Title>TITLE</Title>
<Description>DESCRIPTION</Description>
<Products>false</Products>
<ActivateDate>2018-01-12</ActivateDate>
</Site>
</Category>
<Category>
<Name>CAT 2</Name>
<Site>
<Id>ID 1</Id>
<PopularityRank>1</PopularityRank>
<Title>TITLE</Title>
<Description>DESCRIPTION</Description>
<Products>false</Products>
<ActivateDate>2018-01-12</ActivateDate>
</Site>
<Site>
<Id>ID 2</Id>
<PopularityRank>1</PopularityRank>
<Title>TITLE</Title>
<Description>DESCRIPTION</Description>
<Products>false</Products>
<ActivateDate>2018-01-12</ActivateDate>
</Site>
<Site>
<Id>ID 3</Id>
<PopularityRank>1</PopularityRank>
<Title>TITLE</Title>
<Description>DESCRIPTION</Description>
<Products>false</Products>
<ActivateDate>2018-01-12</ActivateDate>
</Site>
</Category>
</Catalog>

Это дерево

Catalog
--Category
-----Name
-----Site
---------еще
---------еще
---------еще
-----Site
---------еще
---------еще
---------еще
--Category
-----Name
-----Site
---------еще
---------еще
---------еще
-----Site
---------еще
---------еще
---------еще

У меня все работает но до тех пор, когда первая категория заканчивается, скрипт не переходит ко второй категории $xml = $read->Category->Site;

Пробовал добавить после $read = simplexml_load_file($file);

foreach($read->Catalog->Category as $category) {
  $site = $category->Site[0];
}

или

foreach($read->Category as $category) {
  $site = $category->Site[0];
}

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

Как научить скрипт при завершении получения данных из первой категории, переходить к следующей и так до конца?

Мне предложили вариант решения задачи, но я не могу собрать все воедино :( Пожалуйста, помогите мне.

Вот решение которое мне предложили (в примере код прописан т.е. указан не url файла + основные данные которые мне нужны находятся в <Site>...</Site>):

<?php
$xml = '<Catalog>
<Category>
<Name>Категория 1</Name>
<Site>...</Site>
<Site>...</Site>
<Site>...</Site>
</Category>
<Category>
<Name>Категория 2</Name>
<Site>...</Site>
<Site>...</Site>
<Site>...</Site>
</Category>
<Category>
<Name>Категория 3</Name>
<Site>...</Site>
<Site>...</Site>
<Site>...</Site>
</Category>
</Catalog>';
$doc = simplexml_load_string($xml);
$batch = [];
$i = 1;
foreach($doc->Category as $cat) {
    $batch[] = [
        'index' => $i,
        'name' => $cat->Name->getName(),
        'site' => $cat->Site[0]->getName(),
];
if ($i % 1000 == 0) {
    saveBatch($batch);
}
  $i++;
}
saveBatch($batch);

function saveBatch($batch) {
    if (count($batch) > 0) {
        echo "<pre>Saved\n";
        print_r($batch);
    $batch = [];
    }
}

Пожалуйста, помогите собрать скрипт, чтобы он сохранял данные из всех категорий в XML файле в базу данных MySQL.

Было бы идеаль, если бы он еще и по категориям сортировал данные в базе MySQL.

Answer 1

$read->Category->Site значит взять узлы Site у первого узла Category. Всё.

Чтобы обходить все нужные узлы требуется брать верхний узел и итерироваться по нему:

foreach ($read->Category as $category) {
    print_r($category->Name);
    foreach ($category->Site as $site) {
        print_r($site);
    }
}
READ ALSO
Вывод записей из БД автоматически

Вывод записей из БД автоматически

У меня есть две кнопки, при нажатии на которые идет вывод постов из БД (с сортировкой)

140
dle проверка на нахождении в категории

dle проверка на нахождении в категории

Нужно в fullstorytpl, в материалах отдельной категории выводить сообщение Каким образом это можно сделать?

151
Мультизагрузка изображений на сайт

Мультизагрузка изображений на сайт

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

132