2015-02-11 2 views
0

Так у меня есть файл Xml какPHP петли дома Xml Повсеместно элементы сохраняют детско

<cars> 
    <id>1</id> 
    <photos> 
     <img>http://sit.com/img.jpg</img> 
     <img>http://sit.com/img.jpg</img> 
     <img>http://sit.com/img.jpg</img> 
     <img>http://sit.com/img.jpg</img> 
    </photos> 
</cars> 

Так что мне нужно изменить все имя тега альтернативу, и мне нужно получить что-то вроде

<cars> 
    <ex_id>1</ex_id> 
    <images> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
    </images> 
</cars> 

Моего кода является

foreach ($dom->getElementsByTagName('cars') as $item) { 
    for ($i = 0; $i < $item->childNodes->length; ++$i) { 
     $car = $item->childNodes->item($i); 
     $NewElement = $dom->createElement($newName,$value); 
     $car->parentNode->replaceChild($NewElement->cloneNode(TRUE), $car); 
    } 
} 

ли что-то подобное

<cars> 
    <ex_id>1</ex_id> 
    <images/> 
</cars> 

Так вырезаны все детско из <photos>, поэтому мой вопрос заключается в том, чтобы сохранить детей, а также изменить ДЕТСКИЕ теги <img> к <photo>

ответ

1

Вот несколько вопросов:

  1. getElementByTagName() и $ childNodes возвращают «живые» списки, они меняются, если вы меняете DOM. Вы можете использовать iterator_to_array(), чтобы скопировать их в массив.

  2. Здесь представлены не только узлы элементов. Комментарии, разделы cdata и текст (даже содержащие только пробелы) также являются узлами. Если вы выполните итерацию $ childNodes, вам придется проверить тип DOMNode :: $ nodeType.

  3. Не используйте второй аргумент DOMDocument :: createElement(). У него сломанное ускорение. Создайте текстовый узел и добавьте его.

1 и 2 уходят, если вы используете Xpath для извлечения узлов.

$dom = new DOMDocument(); 
$dom->loadXml($xml); 
$xpath = new DOMXPath($dom); 

foreach ($xpath->evaluate('/cars/images/img') as $photo) { 
    $newNode = $dom->createElement('photo'); 
    $newNode->appendChild($dom->createTextNode($photo->textContent)); 
    $photo->parentNode->replaceChild($newNode, $photo); 
} 

echo $dom->saveXml(); 

Выход:

<?xml version="1.0"?> 
<cars> 
    <ex_id>1</ex_id> 
    <images> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
     <photo>http://sit.com/img.jpg</photo> 
    </images> 
</cars> 

Изменение документа DOM часто плохая идея. Это проще для извлечения данных из исходного документа и создать новый целевой документ:

$source = new DOMDocument(); 
$source->loadXml($xml); 
$xpath = new DOMXPath($source); 

$target = new DOMDocument(); 
$target->formatOutput = TRUE; 

$cars = $target->appendChild($target->createElement('cars')); 
$cars 
    ->appendChild($target->createElement('ex_id')) 
    ->appendChild(
     $target->createTextNode(
     $xpath->evaluate('string(/cars/id)') 
    ) 
    ); 

$images = $cars->appendChild($target->createElement('images')); 

foreach ($xpath->evaluate('/cars/photos/img') as $photo) { 
    $images 
    ->appendChild($target->createElement('photo')) 
    ->appendChild($target->createTextNode($photo->textContent)); 
} 

echo $target->saveXml(); 

Выход:

<?xml version="1.0"?> 
<cars> 
    <ex_id>1</ex_id> 
    <images> 
    <photo>http://sit.com/img.jpg</photo> 
    <photo>http://sit.com/img.jpg</photo> 
    <photo>http://sit.com/img.jpg</photo> 
    <photo>http://sit.com/img.jpg</photo> 
    </images> 
</cars> 

Вот язык, посвященные трансформации XML - XSLT. XSLT поддерживается PHP ext/xsl.

+0

Спасибо за ответ, но я думаю, вы не понимаете, что я хочу делать. Я не могу изменить свой код beacause, тогда мне нужно изменить весь мой проект. Мне просто нужно добавить две строки в мой существующий код, чтобы исправить мою проблему –