2015-02-11 56 views
0

所以我有這樣PHP DOM的Xml循環throught元素保持兒童

<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> 

一個XML文件,所以我需要所有的標籤名稱更改爲替代,我需要得到像

<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()的第二個參數。它有一個突破逃脫。創建一個文本節點並追加它。

如果您使用Xpath來獲取節點,則1和2會消失。

$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

感謝您的回答,但我認爲你不明白我想要做什麼。我不能改變我的代碼,因爲那時我需要改變我的所有項目。我只需要添加兩個字符串到我現有的代碼來解決我的問題 – 2015-02-11 14:21:15