2014-02-27 40 views
1

我有兩個具有相似結構的xml文件,我需要根據一個公共屬性合併它們。爲了更加明確,這裏有兩個樣本:根據公共屬性合併兩個xml文件

file1.xml

<Products> 
<record ProductId="366" ProductName="Test" ProductCategory="Categ1"></record> 
</Products> 

file2.xml

<Productprices> 
<record ProductId="366" ProductPrice="10" ProductVAT="24"></record> 
</Productprices> 

的共同屬性,這兩個文件是產品編號。我需要合併所有屬性,使合併後的文件應該是這樣的:

<Products> 
<record ProductId="366" ProductName="Test" ProductCategory="Categ1" ProductPrice="10" ProductVAT="24"></record> 
</Products> 

不幸的是,我已經設法到目前爲止做的僅僅是合併這兩個文件,合併文件看起來是這樣的:

<Products> 
<record ProductId="366" ProductName="Test" ProductCategory="Categ1"></record> 
<record ProductId="366" ProductPrice="10" ProductVAT="24"></record> 
</Products> 

這是我使用的PHP代碼:

$doc1 = new DOMDocument(); 
$doc1->load('file1.xml'); 
$doc2 = new DOMDocument(); 
$doc2->load('file2.xml'); 
$res1 = $doc1->getElementsByTagName('Products')->item(0); 
$items2 = $doc2->getElementsByTagName('record'); 
for ($i = 0; $i < $items2->length; $i ++) { 
$item2 = $items2->item($i); 
$item1 = $doc1->importNode($item2, true); 
$res1->appendChild($item1); 
} 
$doc1->save('file1.xml'); 

有什麼辦法,我可以根據使用的DomDocument共同融合產品編號的所有屬性到一個記錄?我寧願不進入XSLT。

任何幫助將不勝感激。

在此先感謝。

回答

2

attribute()功能我使用XPath從DOM節點讀取和價值觀。在你的情況下,我看到兩個任務。

一個迭代文檔中所有記錄元素的任務,從第二個文檔中獲取匹配元素的屬性並複製屬性。

迭代第二個文檔中的所有記錄元素並將它們添加到第一個的其他任務(如果這裏沒有帶有該ProductId的元素)。

$xmlOne = <<<'XML' 
<Products> 
<record ProductId="366" ProductName="Test" ProductCategory="Categ1"></record> 
</Products> 
XML; 

$xmlTwo = <<<'XML' 
<Productprices> 
<record ProductId="366" ProductPrice="10" ProductVAT="24"></record> 
<record ProductId="444" ProductPrice="23" ProductVAT="32"></record> 
</Productprices> 
XML; 

$targetDom = new DOMDocument(); 
$targetDom->loadXml($xmlOne); 
$targetXpath = new DOMXpath($targetDom); 

$addDom = new DOMDocument(); 
$addDom->loadXml($xmlTwo); 
$addXpath = new DOMXpath($addDom); 

// merge attributes of record elements depending on ProductId 
foreach ($targetXpath->evaluate('//record[@ProductId]') as $record) { 
    $productId = $record->getAttribute('ProductId'); 
    foreach ($addXpath->evaluate('//record[@ProductId='.$productId.']/@*') as $attribute) { 
    if (!$record->hasAttribute($attribute->name)) { 
     $record->setAttribute($attribute->name, $attribute->value); 
    } 
    } 
} 

// copy records elements that are not in target dom 
foreach ($addXpath->evaluate('//record[@ProductId]') as $record) { 
    $productId = $record->getAttribute('ProductId'); 
    if ($targetXpath->evaluate('count(//record[@ProductId='.$productId.'])') == 0) { 
    $targetDom->documentElement->appendChild(
     $targetDom->importNode($record) 
    ); 
    } 
} 

echo $targetDom->saveXml(); 
+0

看起來不錯,但是我遇到了一個小問題(我在這方面很新穎)。我試圖加載這樣的兩個XML文件:$ xmlOne ='/var/www/html/test/file1.xml'和$ xmlTwo ='/var/www/html/test/file2.xml',但我得到在PHP中的以下錯誤:DOMDocument :: loadXML()期望參數1是字符串,對象給出在...我試過一切,我可以找到將XML對象變成一個字符串,但我不能得到任何工作。你能否指點我正確的方向?非常感謝你。 –

+0

DOMDocument :: loadXml()用於xml字符串,DOMDocument :: load()用於xml文件。 – ThW

+0

得到它的工作。我欠你一個,非常感謝。 –

0

可以使用的SimpleXML

$xml = simplexml_load_file($filename); 
foreach($xml->Products->record->attributes() as $attribute => $value) { 
    //do something 
}