如何在PHP中合并多个XML文件

时间:2018-01-25 09:13:25

标签: php xml merge

我是PHP编程的新手,非常感谢我能得到的任何帮助。我有一个看起来像下面的Xml文件..

<?xml version="1.0" encoding="UTF-8"?>
      <results>
        <test external_id="123">
           <result>p</result>
        </test>
        <test external_id="1237">
           <result>p</result>
        </test>
        <test external_id="234">
           <result>p</result>
        </test>
        <test external_id="678">
            <result>p</result>
        </test>
     </results>

XML文件是从testrun生成的。现在,有时测试可能会中断,并会重新生成另一个xml文件,该文件可能包含与第一个xml文件中生成的值类似的值。例如,Xml文件2可能包含以下值

<?xml version="1.0" encoding="UTF-8"?>
    <results>
     <test external_id="412">
        <result>p</result>
     </test>
     <test external_id="234">
        <result>p</result>
     </test>
     <test external_id="123">
        <result>p</result>
     </test>
     <test external_id="745">
        <result>p</result>
     </test>
    </results>

我需要编写一个PHP脚本来将生成的不同XML文件合并到一个XML文件中,而不需要重复。在最终的xml文件中只应出现一次(test external_id =“XXX”)。在测试运行期间可能会生成2个以上的XML文件。我已经搜索了stackoverflow上给出的各种解决方案,但无法得到它。我已经能够合并文件,但副本仍然存在。到目前为止我写的是什么。感谢您的预期帮助。

<?php

$doc1 = new DOMDocument();
$doc1->load('11.xml');

$doc2 = new DOMDocument();
$doc2->load('12.xml');

// get 'results' element of document 1
$res1 = $doc1->getElementsByTagName('results')->item(0);

// iterate over 'testcase' elements of document 2
$items2 = $doc2->getElementsByTagName('test');
for ($i = 0; $i < $items2->length; $i ++) {
        $item2 = $items2->item($i);

// import/copy item from document 2 to document 1
 $item1 = $doc1->importNode($item2, true);

// append imported item to document 1 'res' element
$res1->appendChild($item1);

    }

$doc1->save('merged.xml'); //saving into xml file


$seen=array();

$doc3 = new DOMDocument();
$doc3->load('merged.xml');

$results = $doc3->getElementsByTagName('test');
foreach($results as $test){
    //$key=$doc3->$test;
    if (isset($seen[$test])) {
        unset($doc3->$test);
    }else{
        $seen[$test]=1;
    }
}

echo $doc3->asXML();
?>

1 个答案:

答案 0 :(得分:0)

使用您拥有的两个文件,可以更轻松地获取1个文件并从另一个文件中添加元素。首先,它检查节点是否已存在(使用XPath并计算具有相同ID的元素数)。如果该节点尚不存在,则必须先将该节点从一个文档导入另一个文档,然后将其添加到根元素中。

$doc1 = new DOMDocument();
$doc1->load('NewFile.xml');   // Change file names as needed.
$xp = new DOMXPath($doc1);

$doc2 = new DOMDocument();
$doc2->load('NewFile1.xml');

$test1 = $doc2->getElementsByTagName('test');
foreach ( $test1 as $testItem ) {
    $id = $testItem->getAttribute('external_id');
    if ( $xp->evaluate("count(//test[@external_id='{$id}'])") == 0 )  {
        $copyNode = $doc1->importNode($testItem, true);
        $doc1->documentElement->appendChild($copyNode);
    }
}

echo $doc1->saveXML();

XPath不是最快的运行方式,但是这样做更容易,而不必循环遍历文档(恕我直言)。

如果您拥有大型文件,这不是最佳解决方案,因为它保存了两个文档的内存中的所有内容。