Привет, товарищи из StackO.
В последний день я работал над решением для экспорта определенных значений из разных таблиц в один файл XML. Основная проблема: у меня было три уровня вложенных таблиц. Поскольку у меня были проблемы с написанием этих функций, я хотел бы поделиться своими знаниями с вами.
я использовал XMLWriter а также XMLReader за это
Вот макет файла XML, который должен быть конечным результатом:
<Table 1 Col1=".." Col2="..">
<Table 2 Col1="...">
<Table3 Col1=".." Col2="" Col3=".." Col4="..." />
<Table3 Col1=".." Col2="" Col3=".." Col4="..." />
<Table3 Col1=".." Col2="" Col3=".." Col4="..." />
</Table2>
<Table1>
<Table1>....</Table>
</Table>
</Table2>
<Table1 Col1="xxx" Col2="xxx">
...
Они ссылаются на имена таблиц: -> «имя таблицы». Я буду продолжать использовать этот шаблон для этого примера.
Для решения; посмотри на экспорт часть в ответе.
После того, как мне удалось экспортировать эти значения и создать файл, я хотел сделать это задом наперед. Поэтому мне пришлось импортировать этот файл. Этот случай был немного сложным. Для этого прочитайте Импортировать часть.
Надеюсь, это кому-нибудь поможет.
PS: отдельное спасибо Крейг Рингер кто мне очень помог с этой функцией.
экспорт
Как я уже говорил, я буду использовать XMLWriter для этого случая.
Сначала вы должны написать стандартную часть вверху функции:
$xml = new XMLWriter();
$xml->openURI($file);
$xml->setIndent(true);
$xml->startDocument('1.0','UTF-8');
Затем вы начинаете новый запрос и выбираете первую таблицу (таблица1). Условные обозначения: Основной ключ
$query = new data_DataBaseQuery();
$sql = '
SELECT
*(table1).table1pk* AS "*table1pk*", (table1).col1 AS col1, (table1)."col1" AS col1
FROM
table1
ORDER BY "*table1pk*"';
После успешного выполнения запроса начните извлекать строки, ярлык t1 = table1
if ($query->doQuery($sql) && $query->num_rows()) {
$rows_t1 = $query->fetch_all();
foreach ($rows_t1 as $row_t1) {
$*table1pk* = $row_k['*table1pk*'];
$col1 = $row_t1['col1'];
$col2 = $row_t1['col1'];
Начните записывать значения в файл XML
$xml->startElement("Table1");
$xml->writeAttribute('Col1', $col1);
$xml->writeAttribute('Col1', $col1);
Хорошо, теперь у вас есть такой вывод:
<Table 1 Col1=".." Col2=".."/>
Теперь мы можем повторно использовать нашу функцию для следующей итерации. Мы просто меняем имена таблиц, переменных и имена выходных данных.
Вывод будет выглядеть так:
<Table 1 Col1=".." Col2="..">
<Table 2 Col1="..."/>
</Table1>
Для следующего мы начинаем новую итерацию и так далее. Окончательный вывод должен выглядеть так, как в оригинальном посте. Не забудьте закрыть петли и правильно завершить элементы. В противном случае это может выглядеть странно. В этом случае ваш конец должен выглядеть так:
$xml->endElement(); // End Table3
}
}
$xml->endElement(); // End Table2
}
}
$xml->endElement(); // End Table1
}
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
Импортировать
Для импорта мы обращаем логику экспорта. Для этого мы используем XMLReader, который является курсором, как читатель для файлов XML. В нашем случае хорошее решение, так как он может различать элементы и атрибуты Attribute = «…».
Сначала мы запускаем новый читатель
читатель = новый XMLReader ();
if ($reader->open("filename.xml")) {
while($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT &&reader->name == 'Table 1') {
Он выбирает все записи с именем элемента «Таблица 1»
$col1 = $reader->getAttribute('Col1');
$col1 = $reader->getAttribute('Col2');
Читатель ищет атрибуты и помещает их в значения.
Затем вам нужно выбрать таблицы и столбцы, в которые вы хотите вставить данные, и позволить SQL сделать все остальное.
$SQL = "";
$SQL .= "SELECT
(table1).col1 AS col1, (table1).col2 AS col1
FROM
table1
";
$SQL .= "INSERT INTO table1 (";
$SQL .= "col1, col1";
$SQL .= ") VALUES (";
$SQL .= "'".$col1."', '".$col1."'";
$SQL .= ");".PHP_EOL;
echo $SQL;
}
Вы можете использовать echo
чтобы проверить это на вашем сервере и удалить его в вашей действующей системе.
Теперь мы вставили все выбранные значения, поэтому echo
должен напечатать ваш запрос без синтаксиса PHP.
Теперь вы можете продолжить импорт следующего элемента, который является таблицей 2 с той же функцией и таблицей 3 и т. Д.
if ($reader->nodeType == XMLReader::ELEMENT
&&reader->name == 'Table 2') { ......}
if ($reader->nodeType == XMLReader::ELEMENT
&&reader->name == 'Table 3') { ......}
}
$reader->close();
}
Не забудьте закрыть ридер в конце функции 🙂
Итак, это мое решение до сих пор. Если я найду какие-либо варианты для оптимизации этого кода, я буду и надеюсь, что это поможет некоторым пользователям StackO.
Пожалуйста, не стесняйтесь комментировать и улучшать этот код.
Других решений пока нет …