2016-03-28 59 views
0

我有一個令人難以置信的任務。我有一個直接向前的飼料。出租屬性要精確,看起來像這樣:使用父子元素重新創建XML Feed

<ad> 
<name>Property 1</name> 
<latitude>29.723085</latitude> 
<longitude>-95.66024</longitude> 
<area>2000</area> 
</ad> 
<ad> 
<name>Property 1</name> 
<latitude>29.723085</latitude> 
<longitude>-95.66024</longitude> 
<area>2500</area> 
</ad> 

在上面的例子中,有一個屬性有兩個不同的單位。唯一的共同點是名稱和緯度,經度字段。

現在,我需要使用PHP將這個XML重新創建爲新的,並將所有不同的單元放置到一個屬性中。所以新的飼料將如下所示:

<ad> 
<property_name>Property 1</property_name> 
<latitude>29.723085</latitude> 
<longitude>-95.66024</longitude> 
<units> 
    <unit> 
     <area>2000</area> 
    </unit> 
    <unit> 
     <area>2500</area> 
    </unit> 
</units> 
</ad> 

有人可以幫我解決這個問題嗎?非常感謝

+0

我投票結束這個問題作爲題外話,因爲它是一個「寫我的代碼」的需求張貼爲一個問題。 – michi

回答

1

還有更多選項可以獲得您想要的結果。使用DOMDocument您可以使用importNode,或者您可以直接修改原始XML。

我將向您展示一種創建全新XML的方法。

首先,你必須在DOMDocument對象加載現有的XML:

$src = new DOMDocument(); 
libxml_use_internal_errors(1); 
$src->loadXML($xml); 

然後創建目標DOMDocument對象。爲此,我使用通用<root>標籤;你可以用你的完整的XML包裝<ad>標籤替換:

$dom = new DOMDocument(); 
libxml_use_internal_errors(1); 
$dom->loadXML('<root></root>'); 
$dom->formatOutput = True; 
$root = $dom->getElementsByTagName('root')->item(0); 

現在,初始化爲目標XML一個DOMXpath對象。DOMXPath允許執行復雜的XML查詢:

$xpath = new DOMXPath($dom); 

在這一點上,執行foreach通過源XML的所有<ad>節點 - 對每個節點 - 檢索<name><area>值:

foreach($src->getElementsByTagName('ad') as $node) 
{ 
    $name = $node->getElementsByTagName('name')->item(0)->nodeValue; 
    $area = $node->getElementsByTagName('area')->item(0)->nodeValue; 

現在使用DOMXPath找到目標XML中是否已有<ad>節點<name> value =檢索的名稱:

$found = $xpath->query('//ad[name[.="'.$name.'"]]'); 

如果找到目的地節點,設定其<units>$child

if($found->length) 
    { 
     $child = $found->item(0)->getElementsByTagName('units')->item(0); 
    } 

否則,建立一個新節點從源添加鹼數據,然後將其設置爲$child

else 
    { 
     $lat = $node->getElementsByTagName('latitude')->item(0)->nodeValue; 
     $long = $node->getElementsByTagName('longitude')->item(0)->nodeValue; 

     $child = $dom->createElement('ad'); 

     $child->appendChild($dom->createElement('name', $name)); 
     $child->appendChild($dom->createElement('latitude', $lat)); 
     $child->appendChild($dom->createElement('longitude', $long)); 
     $child->appendChild($dom->createElement('units')); 

     $root->appendChild($child); 

     $child = $child->getElementsByTagName('units')->item(0); 
    } 

此時,您有正確的$child節點來添加<unit>

$unit = $dom->createElement('unit'); 
    $unit->appendChild($dom->createElement('area', $area)); 
    $child->appendChild($unit); 
} 

foreach()循環結束時,你可以打印所獲得的XML:

echo $dom->saveXML(); 

輸出:

<?xml version="1.0"?> 
<root> 
    <ad> 
    <name>Property 1</name> 
    <latitude>29.723085</latitude> 
    <longitude>-95.66024</longitude> 
    <units/> 
    <unit> 
     <area>2000</area> 
    </unit> 
    <unit> 
     <area>2500</area> 
    </unit> 
    </ad> 
</root> 

eval.in demo


附加說明:

在上面的腳本中,我假設每個屬性名稱都有唯一的long/lat。如果可以存在具有相同名稱但不同長/緯度的屬性,則必須不僅按名稱查找節點,還要按緯度/經度查找節點。

我還假設你的結構樣本在每個節點都受到尊重。否則,像$node->getElementsByTagName('latitude')->item(0)->nodeValue CAN語法失敗,你必須將其替換:

if($node->getElementsByTagName('latitude')->length) 
{ 
    $lat = $node->getElementsByTagName('latitude')->item(0)->nodeValue; 
} 

等與->item(0)語法每行代碼。

相關問題