Frage

Been trying many different scripts and ended up with this one that I feel must be close to a solution, but not sure how to define the child. Tried "@name" and "name". All the scripts I've tried is copied from here and there and modified for my use.

The XMLs have 1 node and 1 child each. Should not be much easier then this, but no luck. Can mention that I also want the xsl stylesheet reference merged, but I think I just stumbeled over a solution for that, but forgot to bookmark the page.

xml 1:

<?xml version="1.0" encoding="utf-8"?>
<companyroutes>
  <route name="BBUPLOAD">ENGM OKSAT L996 SVD EKCH</route>

</companyroutes>

xml 2:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xml" href="merge2.xsl"?> 
<companyroutes>
   <route name="XXXXCORE">RUTA TULLA L666 BARE LITT MNOP</route>

</companyroutes>

And the PHP code (this file resides in the same dir as the output file:

  <?php
    $doc1 = new DOMDocument();
    $doc1->load('/uploads/companyroutes.xml');

    $doc2 = new DOMDocument();
    $doc2->load('/uploads/companyroutes_core.xml');

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

    // iterate over '@name' elements of document 2
    $companyroutes2 = $doc2->getElementsByTagName('name');
    for ($i = 0; $i < $companyroutes2->length; $i ++) {
        $name2 = $companyroutes2->name($i);

        // import/copy @name from document 2 to document 1
        $name1 = $doc1->importNode($name2, true);

        // append imported @name to document 1 'res' element
        $res1->appendChild($name1);

    }
    $doc1->save('companyroutes.xml'); 
    ?>

Any pointers appreciated.

War es hilfreich?

Lösung

Here's how to merge the files with simplexml:

$xml = simplexml_load_string($x1); // assume XML in $x1 and $x2
$xml2 = simplexml_load_string($x2);

foreach ($xml2->route as $route) {  // merge $xml2 into $xml
    $newroute = $xml->addChild("route", $route);
    $newroute->addAttribute("name", $route['name']);
}

unset($xml2); // dispose $xml2

echo $xml->asXML();

see it working: https://eval.in/97372

Andere Tipps

Two steps, prepare the target DOM (add the document element). Load each source XML, traverse the child nodes inside the document element and import them into your target document:

$xmlFiles = [
  '/uploads/companyroutes.xml',
  '/uploads/companyroutes_core.xml'
];

$targetDom = new DOMDocument();
$targetDom->appendChild(
  $targetDom->createProcessingInstruction(
    'xml-stylesheet', 'type="text/xml" href="merge2.xsl"' 
  )
);
$rootNode = $targetDom->appendChild(
  $targetDom->createElement('companyroutes')
);

foreach ($xmlFiles as $xmlFile) {
  $importDom = new DOMDocument();
  $importDom->load($xmlFile);
  foreach ($importDom->documentElement->childNodes as $node) {
    $rootNode->appendChild($targetDom->importNode($node, TRUE));
  }
}

echo $targetDom->saveXml();

An example with XML strings as sources: https://eval.in/97405

Of course you could create a template XML for the target DOM and just load it:

$template = <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xml" href="merge2.xsl"?> 
<companyroutes/>
XML;

$targetDom = new DOMDocument();
$targetDom->loadXml($template);
$rootNode = $targetDom->documentElement;
...

I would not suggest changing a document. If you build a new document you can repeat the action.

Thanks. I did a little edit and got it running.

$xml = simplexml_load_file('./uploads/companyroutes_core.xml');  // xml files URL insted of $x
$xml2 = simplexml_load_file('./uploads/companyroutes.xml');

foreach ($xml2->route as $route) {  // merge $xml2 into $xml
    $newroute = $xml->addChild("route", $route);
    $newroute->addAttribute("name", $route['name']);
}

unset($xml2); // dispose $xml2

$xml->asXML('merged.xml'); //this line saves to directory and name of choice

My only problem now is that all Childs is output on one single line. A 4Mb long line. Need it to be more tidy (yes I've read about tidy commands, but how to use it here...? idunno) and breake it up for each child. Thanks for the patience so far. Don't be suppriced if you see me asking more basic questions, but the good thing is that I learn more each day I struggle with it.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top