根据通用属性合并两个xml文件 [英] Merge two xml files based on common attribute

查看:78
本文介绍了根据通用属性合并两个xml文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个具有相似结构的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆