根据通用属性合并两个xml文件 [英] Merge two xml files based on common attribute
问题描述
我有两个具有相似结构的xml文件,我需要根据一个公共属性来合并它们.更明确地说,这是两个示例:
I have two xml files with a similar structure, and I need to merge them based on a common attribute. To be more explicit, here are two samples:
file1.xml
file1.xml
<Products>
<record ProductId="366" ProductName="Test" ProductCategory="Categ1"></record>
</Products>
file2.xml
file2.xml
<Productprices>
<record ProductId="366" ProductPrice="10" ProductVAT="24"></record>
</Productprices>
两个文件中的通用属性是ProductId.我需要合并所有属性,以便合并后的文件看起来像这样:
The common attribute in both files is ProductId. I need to merge all the attributes so that the combined file would look like this:
<Products>
<record ProductId="366" ProductName="Test" ProductCategory="Categ1" ProductPrice="10" ProductVAT="24"></record>
</Products>
不幸的是,到目前为止,我所要做的只是简单地合并两个文件,合并后的文件看起来像这样:
Unfortunately, all I have managed to do so far is simply merge the two files, the merged file looks like this:
<Products>
<record ProductId="366" ProductName="Test" ProductCategory="Categ1"></record>
<record ProductId="366" ProductPrice="10" ProductVAT="24"></record>
</Products>
这是我使用的PHP代码:
This is the PHP code I used:
$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将基于通用ProductId的所有属性合并到一条记录中?我宁愿不参加XSLT.
Is there any way I can merge all the attributes into one record based on the common ProductId by using DomDocument? I would rather not go into XSLT.
任何帮助将不胜感激.
谢谢.
推荐答案
我使用Xpath从DOM中获取节点和值.在您的情况下,我看到两个任务.
I use Xpath to fetch nodes and values from DOM. In your case I see two tasks.
一项任务是遍历文档中的所有记录元素,从第二个文档中获取匹配元素的属性,然后复制属性.
One task to iterate all record elements in on document, fetch the attributes of the matching element from the second document and copy the attributes.
另一个任务是迭代第二个文档中的所有记录元素,如果此处没有该ProductId的元素,则将它们添加到第一个文档中.
The other task to iterate all record elements in the second document and add them to the first if here is no element with that 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();
这篇关于根据通用属性合并两个xml文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!