Сравните два XML-файла, обновите / объедините и сохраните - php simplexml - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь использовать simplexml для сравнения и дополнения одного XML-файла элементами из другого.Так как я новичок, я пытался найти подходящий пример для этой проблемы, но дни поиска почти ничего не значат: только кусочки.Этот первый черновик немного, но я надеюсь, что кто-то может дать мне несколько указателей.

Исходный XML-файл: catalog.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <item>
    <name>King of Hearts</name>
    <category>playing cards</category>      
    <class>Hearts</class>
    <filter>King</filter>
  </item>
  <item>
    <name>Ace of Spades</name>
    <category>playing cards</category>
    <class>Spades</class>
    <filter>Ace</filter>
  </item>
  <item>
    <name>Eight of Diamonds</name>
    <category>playing cards</category>  
    <class>Diamonds</class>
    <filter>Eight</filter>
  </item>
</catalog>

Целевой XML-файл: user.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <item>
    <name>Ace of Spades</name>
    <category>playing cards</category>
    <class>Spades</class>
    <filter>Ace</filter>
  </item>
  <item>
    <name>Knight of Clubs</name>
    <category>playing cards</category>  
    <class>Clubs</class>
    <filter>Knight</filter>
  </item>
</catalog>

Обновленный файл пользователя после сравнения / слияния: user-updated.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <item>
    <name>Ace of Spades</name>
    <category>playing cards</category>
    <class>Spades</class>
    <filter>Ace</filter>
  </item>
  <item>
    <name>Knight of Clubs</name>
    <category>playing cards</category>
    <class>Clubs</class>
    <filter>Knight</filter>
  </item>
  <item>
    <name>King of Hearts</name>
    <category>playing cards</category>
    <class>Hearts</class>
    <filter>King</filter>
  </item>
  <item>
    <name>Eight of Diamonds</name>
    <category>playing cards</category>
    <class>Diamonds</class>
    <filter>Eight</filter>
  </item>
</catalog>

Код PHP: merge.php

<?php

// catalog.xml in this example contains two extra items as user.xml
// these 'excess items' need to bee updated/copied from catalog.xml to user.xml
// the final order of items in user-updated.xml is of no concern: 
// so it's probably easiest to just add them after the last existing item?

// 1. load data from catalog.xml & user.xml (which have the same root & structure)

$catalog = 'catalog.xml';
$user = 'user.xml';

$sourcexml = simplexml_load_file($catalog);
$targetxml = simplexml_load_file($user);

// 2. compare data and return nodes missing in user.xml

$result = array_diff($targetxml, $sourcexml);

// 3. add missing items (including children) to $targetxml

foreach($result->item as $item) {
    $xml = $targetxml->addChild($item);
    $xml->addChild('name', $item->name);
    $xml->addChild('category', $item->category);
    $xml->addChild('class', $item->class);
    $xml->addChild('filter', $item->filter);        
}

// 4. save updated $targetxml to user.xml

$targetxml->asXML('user-updated.xml');

?>

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Я написал лучший код для вас.Вы можете объединить 2 или более XML-файлов.

<?php

$files = array('catalog.xml', 'user.xml');
$xml = combine_xmls($files);

echo $xml->asXML();


function combine_xmls($files, $key='name'){

    foreach ($files as $file){
        $a = json_decode(json_encode(simplexml_load_file($file)),true);
        $b[] = $a['item'];
    }

    $b = call_user_func_array('array_merge', $b);
    foreach($b as $a) $items[$a[$key]] = $a;

    $xml = new SimpleXMLElement('<?xml version="1.0" encoding="ISO-8859-1"?><catalog></catalog>');

    foreach ($items as $item ){
        $node = $xml->addChild('item');
        foreach ($item as $key=>$val) $node->addChild($key, $val);
    }

    return $xml;

}

?>
0 голосов
/ 19 мая 2018

Я написал код для вашей проблемы.Вы можете использовать его без проблем.:)

<?php

$catalog = 'catalog.xml';
$user = 'user.xml';

$sourcexml = simplexml_load_file($catalog);
$targetxml = simplexml_load_file($user);

$a1 = json_decode(json_encode($sourcexml),true);
$a2 = json_decode(json_encode($targetxml),true);

$items = array_map('unserialize', 
    array_unique(
        array_map('serialize', 
            array_merge_recursive($a1['item'], $a2['item'])
        )
    )
);

$xml = new SimpleXMLElement('<?xml version="1.0"?><catalog></catalog>');

foreach ($items as $item){
    $node = $xml->addChild('item');
    $node->addChild('name', $item['name']);
    $node->addChild('category', $item['category']);
    $node->addChild('class', $item['class']);
    $node->addChild('filter', $item['filter']);     
}

echo $xml->asXML();

?>
...