Загрузить XML-файл -> Добавить элементы -> Изменить порядок -> Создать XML-файл [PHP & SimpleXML] - PullRequest
0 голосов
/ 03 сентября 2018

РЕЗЮМЕ

  1. Загрузить существующий XML-файл
  2. Добавить 2 предмета каждому ребенку
  3. Изменить порядок детей
  4. Создать новый XML-файл

ПОДРОБНОЕ ОБЪЯСНЕНИЕ

Это сокращенный образец исходного XML-файла

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<warehouse>
  <inventory>
    <name>Name 1</name>
    <markers>
     <marker>red</marker>
     <marker>yellow</marker>
     <marker>green</marker>
   </markers>
   (...)
  </inventory>
  <inventory>
    <name>Name 2</name>
    <markers>
     <marker>blue</marker>
     <marker>pink</marker>
     <marker>brown</marker>
   </markers>
   (...)
  </inventory>
  <inventory>
    <name>Name 3</name>
    <markers>
     <marker>black</marker>
     <marker>white</marker>
     <marker>marron</marker>
   </markers>
   (...)
  </inventory>
</warehouse>

1. Загрузить существующий XML-файл

Загрузить XML-файл в переменную.

$source_xmlfile = "source.xml";
$source_xml_file_contents = simplexml_load_file($source_xmlfile);

2. Добавьте 2 предмета каждому ребенку

Добавьте 2 детей в первый инвентарь с именем и значением.

$source_xml_file_contents->warehouse->inventory[0]->addChild("new1", "0.12345");
$source_xml_file_contents->warehouse->inventory[0]->addChild("new2", "17");

3. Изменить порядок детей

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

Моя идея заключалась в следующем:

$destination_xml_file_contents = new SimpleXMLElement('<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?><warehouse></warehouse>');
foreach($source_xml_file_contents->warehouse->inventory as $inventory){
  $destination_xml_file_contents->warehouse->addChild("inventory", $inventory);
}

Основная идея заключается в том, что я беру дочерний элемент () из и сохраняю его в переменной или, возможно, массиве (который был бы намного лучше и проще), содержащем все, что содержит (включая атрибуты и дочерние узлы и т. д.). После того, как я сохранил все где-то еще, я беру новый XML и помещаю сохраненные в новом порядке в новый XML.

Однако кажется невозможным сохранить весь дочерний элемент в переменную (или массив) и позже добавить его в другой XML.

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

4. Написать новый XML-файл

Сохранение нового содержимого XML в новый XML-файл.

$new_xml_file = "destination.xml";
$destination_xml_file_contents->asXML($new_xml_file);

Это сокращенный образец XML-файла назначения

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<warehouse>
  <inventory>
    <name>Name 2</name>
    <markers>
     <marker>blue</marker>
     <marker>pink</marker>
     </marker>brown</marker>
   </markers>
   (...)
   <new1>0.6789</new1>
   <new2>115</new2>
  </inventory>
  <inventory>
    <name>Name 1</name>
    <markers>
     <marker>red</marker>
     <marker>yellow</marker>
     </marker>green</marker>
   </markers>
   (...)
   <new1>0.4567</new1>
   <new2>4</new2>
  </inventory>
  <inventory>
    <name>Name 3</name>
    <markers>
     <marker>black</marker>
     <marker>white</marker>
     </marker>marron</marker>
   </markers>
   (...)
   <new1>0.1234</new1>
   <new2>17</new2>
  </inventory>
</warehouse>

Может кто-нибудь помочь мне разобраться, как сделать эту работу?

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

1 Ответ

0 голосов
/ 04 сентября 2018

Есть несколько вещей, в которых я не уверен, но, надеюсь, этот код покажет принцип копирования узлов из одного документа в другой (и добавления контента) с использованием DOMDocument. Я добавил комментарии к коду, чтобы помочь, если есть что-то, в чем вы не уверены, то дайте мне знать.

$inFile = "data.xml";
$input = new DOMDocument();
$input->load($inFile);

$all_inventory = $input->getElementsByTagName("inventory");
// Add new content to each item
foreach ( $all_inventory as $inventory )    {
    $inventory->appendChild ( $input->createElement("new1", "0.12345"));
    $inventory->appendChild ( $input->createElement("new2", "17"));
}

$outFile = "out.xml";
$output = new DOMDocument();
// Create base document for destination
$output->loadXML('<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?><warehouse />');
// Get the root element as we will be adding content to this
$outputRoot = $output->documentElement;
foreach ( $all_inventory as $inventory )    {
    // Copy the element from the input document to the output document
    // Note this does not add it anywhere, just makes it available
    // The true option says make a deep copy
    $import = $output->importNode($inventory, true);
    // Add the newly imported node to the output document root
    $outputRoot->appendChild($import);
}
$output->save($outFile);

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

Также обратите внимание, что в вашем документе есть небольшой недостаток XML ...

</marker>green</marker>
...