2014-02-12 2 views
2

Я предоставил XML-файл с этой структурой:Restructure XML в PHP

<items> 
    <item> 
    <images> 
     <image>A</image> 
     <image>B</image> 
     <image>C</image> 
    </images> 
    . 
    . 
    . 
    </item> 
</items> 

Однако функция импорта моего магазина требуется следующий формат:

<items> 
    <item> 
    <images> 
     <image>A</image> 
     <image1>B</image> 
     <image2>C</image> 
    </images> 
    . 
    . 
    . 
    </item> 
</items> 

Сначала я думал, что я сделал бы это просто на Java, так как было бы довольно легко читать по строкам и реструктурировать документ, но я бы хотел, чтобы он был таким, чтобы я мог просто посетить URL-адрес, и это сделано для меня.

Вот подход, который я взял:

<?php 
$xml = simplexml_load_file('data.xml'); 


// Loop over items in original xml 
for($i = 0; $i < count($xml->item); $i++) 
{ 
    $images; 
    if(($c = count($xml->item[$i]->images->image)) > 1) 
    { 
     $images = $xml->item[$i]->images; 

     // Remove entry 
     unset($xml->item[$i]->images); 

     $xml->item[$i]->addChild('images'); 

     for($y = 0; $y < count($images->image); $y++) 
     { 
      if($y == 0) 
      { 
       $xx = $xml->item[$i]->images->addChild('image', $images->image[$y]); 

      }else { 
       $xml->item[$i]->images->addChild('image' . $y, $images->image[$y]); 
      } 
     } 

     var_dump($images); 
    } 
} 

$xml->asXML('POTO.xml'); 

Дилемма я Тхо, что ни один из Чайлдс не добавляются к изображениям. Мне сказали, что мне нужно реструктурировать весь документ, но это глупо, если я var_dump сразу после удаления узла изображений узел и его дочерние элементы удалены, однако, когда я иду добавить узел изображений обратно к узлу узла и var_dump, узел показывает, что узел был добавлен в узел узла в качестве дочернего элемента, но когда я пытаюсь добавить изображение к изображениям, ничего не добавляется.

Нужно ли мне реструктурировать весь документ, потому что тогда кажется более простым сделать это на Java. Или я что-то упустил.

+2

2 цента: посмотрите [PHP: XSL] (http://www.php.net/manual/ro/book.xsl.php). –

+0

Каково значение 'count ($ xml-> item)' и 'count ($ images-> image)'? Выполнены ли ваши тела петли? –

+0

@GeorgeCummins Синтаксис count выглядел мне смешно, но, похоже, он действителен. Похоже, что PHP 5.3 поддерживал метод объекта 'SimpleXMLElement :: count()', но с использованием основного 'count()' был фактически стандартным до этого. Кто знал? Ссылка: http://us3.php.net/manual/en/simplexmlelement.count.php – eimajenthat

ответ

1

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

Однако в этом случае результатом является то, что при удалении изображений из основного объекта SimpleXML вы также уничтожаете экземпляр в $ images. К счастью, есть решение. Вы можете указать clone объект, а не назначать его. См http://www.php.net/manual/en/language.oop5.cloning.php

Я изменил свой образец кода здесь, и это, кажется, работает: http://3v4l.org/ZmRZV

Edit: очищены мой код немного и включил его:

<?php 
//$xml = simplexml_load_file('data.xml'); 
$xml = simplexml_load_string('<items> 
    <item> 
    <images> 
     <image>A</image> 
     <image>B</image> 
     <image>C</image> 
    </images> 
    </item> 
</items>'); 

// Loop over items in original xml 
foreach ($xml->item as $item) { 
    if (count($item->images->image) > 1) { 
     // Clone entry 
     $images = clone $item->images; 

     // Remove entry and replace with empty 
     unset($item->images); 
     $item->addChild('images'); 

     for ($i = 0; $i < count($images->image); $i++) { 
      $num = ($i > 0) ? $i : ''; 
      $item->images->addChild('image'.$num, $images->image[$i]); 
     } 
    } 
} 

//$xml->asXML('POTO.xml'); 
echo $xml->asXML(); 

Похоже, это не работает до к версии 5.2.1 (http://3v4l.org/m0VoD), но это происходит довольно далеко. Расмус не хочет, чтобы кто-то работал меньше 5.4 (http://www.youtube.com/watch?v=anr7DQnMMs0&t=10m27s), и я склонен согласиться.

Для записи это поведение, копирование только ссылки не является причудой PHP. Это обычная практика. Дополнительная информация: http://en.wikipedia.org/wiki/Cloning_(programming)

Смежные вопросы