Merge XML files in PHP

后端 未结 3 1826
半阙折子戏
半阙折子戏 2020-12-01 12:40

I have 2 files 1.xml and 2.xml both having similar structure and I would like to have one. I tried many solutions but I had errors only - frankly s

相关标签:
3条回答
  • 2020-12-01 12:57

    Since you've put an effort in, I've coded something that should work.

    Note that this is untested code, but you get the idea.

    It's up to you to make it into pretty functions. Make sure you understand what's going on; being able to work with the DOM will probably help you out in a lot of future scenarios. The cool thing about the DOM standard is that you have pretty much the same operations in many different programming languages/platforms.

        $doc1 = new DOMDocument();
        $doc1->load('1.xml');
    
        $doc2 = new DOMDocument();
        $doc2->load('2.xml');
    
        // get 'res' element of document 1
        $res1 = $doc1->getElementsByTagName('res')->item(0);
    
        // iterate over 'item' elements of document 2
        $items2 = $doc2->getElementsByTagName('item');
        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);
    
        }
    
    0 讨论(0)
  • 2020-12-01 13:01

    I think the most simplest way is changing XML to array first, combine two array which are much more easier and straightforward. Finally change array back to xml. It may helps for the situation when you want to combine two XML files directly. You only need to consider which key is the position you wanna add the child nodes.

    function xml_to_array($sxi){
        $a = array();
        for( $sxi->rewind(); $sxi->valid(); $sxi->next() ) {
            if(!array_key_exists($sxi->key(), $a)){
                $a[$sxi->key()] = array();
            }
            if($sxi->hasChildren()){
                $a[$sxi->key()] = $this->xml_to_array($sxi->current());
            }
            else{
                $a[$sxi->key()] = strval($sxi->current());
            }
        }
        return $a;
    }
    function array_to_xml( $data, &$xml_data ) {
        foreach( $data as $key => $value ) {
            if( is_numeric($key) ){
                $key = 'item'.$key; //dealing with <0/>..<n/> issues
            }
            if( is_array($value) ) {
                $subnode = $xml_data->addChild($key);
                array_to_xml($value, $subnode);
            } else {
                $xml_data->addChild("$key",htmlspecialchars("$value"));
            }
        }
    }
    

    Useage: Create a SimpleXMLIterator

    $xml1 = new \SimpleXMLIterator('test1.xml',null,true);
    $a = xml_to_array($xml1); //convert xml to array
    $xml2 = new \SimpleXMLIterator('test2.xml',null,true);
    $b = xml_to_array($xml2);
    $c = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
    $a['new_node']=$b;
    array_to_xml($a,$c);
    var_dump($c);
    
    0 讨论(0)
  • 2020-12-01 13:08

    How about :

    <?php
    // Read file 1
    $xmlfilecontent = file_get_contents('xml1.xml');
    
    // Concat file 2
    $xmlfilecontent .= file_get_contents('xml2.xml');
    
    // remove <items> tags
    preg_replace('/<items[^"]*">/','',$xmlfilecontent);
    
    // remove </items> tags
    $xmlfilecontent = str_replace('</items>','',$xmlfilecontent );
    
    // remove <res> tags
    $xmlfilecontent = str_replace('<res>','',$xmlfilecontent );
    
    // remove </res> tags
    $xmlfilecontent = str_replace('</res>','',$xmlfilecontent );
    
    // load XML Object - also add res and items + amount
    $xmlobj = simple_xml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'.PHP_EOL.'<res>'.PHP_EOL.'<items total="'.substr_count( $xmlfilecontent , '<item>').'">'.PHP_EOL.$xmlfilecontent.PHP_EOL.'</items>'.PHP_EOL.'</res>');
    
    0 讨论(0)
提交回复
热议问题