合并两个XML文件的选定节点

时间:2017-05-25 07:30:52

标签: php xml simplexml domdocument

假设我有两个具有相同结构的XML文件。我需要创建具有相同结构的新XML文件,其中包含来自最初两个XML文件的选定节点。

我将尝试用下面的例子再次解释。

input1.xml

<parent>
    <item id="100">
         ...
    </item>
    <item id="101">
         ...
    </item>
    <item id="102">
         ...
    </item>
    <item id="103">
         ...
    </item>
</parent> 

input2.xml

<parent>
    <item id="200">
         ...
    </item>
    <item id="201">
         ...
    </item>
    <item id="202">
         ...
    </item>
    <item id="203">
         ...
    </item>
</parent> 

现在,我需要从100,103中选择input1.xml的{​​{1}}和202,203的{​​{1}}节点。它也应该是input2.xml的顺序,最终结果看起来像下面。

203,100,103,202

result.xml

如果我可以按照<parent> <item id="203"> ... </item> <item id="100"> ... </item> <item id="103"> ... </item> <item id="202"> ... </item> </parent> 的方式编辑input2.xml,则无需创建新文件,这将是理想的解决方案。

到目前为止我做了什么:

我的方法是首先从result.xml删除节点,然后将节点添加到input2.xml的节点。 我有以下功能从input1.xml文件中删除节点。

例如:call input2.xml可以删除节点200,我可以用类似的方式重复它。

delete_record(200,'input2.xml','result.xml')

但我仍然在努力寻找如何将节点添加到同一function delete_record($id, $input, $output){ $xml = new DOMDocument(); $xml->load($input); $deals = $xml->getElementsByTagName('item'); foreach ($deals as $deal) { $deal_id = $deal->getElementsByTagName('id')->item(0)->nodeValue; if ($deal_id == $id) { $id_matched = true; $deal->parentNode->removeChild($deal); break; } } if ($id_matched == true) { if ($xml->save($output)) { return true; } } } 文件以及如何订购的方法。

任何形式的帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

没有必要乱删除,只需做你需要的。从两个文件中按id选择节点,并按顺序放置:

// merge all nodes by Id
function getNodesById($id, ...$xpaths) {
  $result = [];
  foreach($xpaths as $xpath) {
    foreach($xpath->query("//item[@id='$id']") as $node) {
      $result[] = $node;
    }
  }
  return $result;
}


// load source documents
$xml1 = new DOMDocument();
$xml1->load(....);
$xpath1 = new DomXpath($xml1);

$xml2 = new DOMDocument();
$xml2->load(....);
$xpath2 = new DomXpath($xml2);

// create result document
$result = new DOMDocument();
$parent = $result->createElement("parent");
$result->appendChild($parent);

// populate result document with nodes:
foreach([203, 100, 103, 202] as $id) {
  $nodesToInsert = getNodesById($id, xpath1, xpath2);
  if (count($nodesToInsert) !== 1) {
    // resolve conflicts, if any
    throw new Exception("Id $id is not found or not unique.");
  }
  $parent->appendChild($result->importNode($nodesToInsert[0], true));
}

// or save it to a file
echo $result->saveXml();