還有更多選項可以獲得您想要的結果。使用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)
語法每行代碼。
我投票結束這個問題作爲題外話,因爲它是一個「寫我的代碼」的需求張貼爲一個問題。 – michi