2012-04-15 4 views
17

私は2つのファイル1.xml2.xmlの両方が同様の構造を持っています。私は1つ持っています。私は多くのソリューションを試しましたが、エラーがあっただけです。率直に言えば、スクリプトの仕組みが分かりません。PHPでXMLファイルをマージ

1.xml

<res> 
    <items total="180"> 
     <item> 
      <id>1</id> 
      <title>Title 1</title> 
      <author>Author 1</author> 
     </item> 
     ... 
    </items> 
</res> 

2.xml

<res> 
    <items total="123"> 
     <item> 
      <id>190</id> 
      <title>Title 190</title> 
      <author>Author 190</author> 
     </item> 
     ... 
    </items> 
</res> 

私は、私はそれをどのように行う必要があります

<res> 
    <items total="303"> 
     <item> 
      <id>1</id> 
      <title>Title 1</title> 
      <author>Author 1</author> 
     </item> 
     ... //items from 1.xml 
     <item> 
      <id>190</id> 
      <title>Title 190</title> 
      <author>Author 190</author> 
     </item> 
     ... //items from 2.xml 
    </items> 
</res> 

次の構造を持つ新しいファイルmerged.xmlを作成したいと思いますか?私にそれをする方法を説明できますか?より多くのファイルでどうすればいいですか?おかげ

編集

私が試した何?

function joinXML($parent, $child, $tag = null) 
{ 
    $DOMChild = new DOMDocument; 
    $DOMChild->load($child); 
    $node = $DOMChild->documentElement; 

    $DOMParent = new DOMDocument; 
    $DOMParent->formatOutput = true; 
    $DOMParent->load($parent); 

    $node = $DOMParent->importNode($node, true); 

    if ($tag !== null) { 
     $tag = $DOMParent->getElementsByTagName($tag)->item(0); 
     $tag->appendChild($node); 
    } else { 
     $DOMParent->documentElement->appendChild($node); 
    } 

    return $DOMParent->save('merged.xml'); 
} 

joinXML('1.xml', '2.xml') 

しかし、それは間違ったxmlファイルを作成:

<res> 
    <items total="180"> 
     <item> 
      <id>1</id> 
      <title>Title 1</title> 
      <author>Author 1</author> 
     </item> 
     ... 
    </items> 
    <res> 
     <items total="123"> 
      <item> 
       <id>190</id> 
       <title>Title 190</title> 
       <author>Author 190</author> 
      </item> 
      ... 
     </items> 
    </res> 
</res> 

そして私を、私はのDOMDocumentマニュアルに見て、例を見つけToriousアドバイスに従い

<?php 
function mergeXML(&$base, $add) 
{ 
    if ($add->count() != 0) 
    $new = $base->addChild($add->getName()); 
    else 
     $new = $base->addChild($add->getName(), $add); 
    foreach ($add->attributes() as $a => $b) 
    { 
     $new->addAttribute($a, $b); 
    } 
    if ($add->count() != 0) 
    { 
     foreach ($add->children() as $child) 
     { 
      mergeXML($new, $child); 
     } 
    } 
} 
$xml = mergeXML(simplexml_load_file('1.xml'), simplexml_load_file('2.xml')); 
echo $xml->asXML(merged.xml); 
?> 

EDIT2

このファイルを正しく使用することはできません。私は正しい構造が必要で、ここではあるファイルを別のファイルに貼り付けることがあります。すべてのタグではなく、アイテムだけを「貼り付け」たいと思います。私は何を変えるべきですか?ここ

EDIT3

答えです - あなたが力を入れてきたので、私はコード化されてきた

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

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

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

// 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); 

} 
$doc1->save('merged.xml'); //edited -added saving into xml file 
+0

を作成し、[ここ](http://www.php.net/manual/en/domdocument.loadxml.php)を起動します。 XML文書を別のDOMDocumentソースからマージしたい場合は、ある時点で 'importNode'などを使用しなければならないことに注意してください。 – Torious

答えて

17

編集//チェック - Toriousの回答に基づいて - 私のニーズに合わせて適応うまくいくはずのもの。

これはテストされていないコードであることに注意してください。

かなりの機能にするのはあなた次第です。何が起こっているのかを理解してください。 DOMを使って作業することは、将来の多くのシナリオであなたを助けるでしょう。 DOM標準についてのすばらしい点は、多くの異なるプログラミング言語/プラットフォームでほぼ同じ操作をしていることです。

いかが
$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

+1退屈なdomの翻訳の場合 – worenga

+0

ありがとうございます。私はいくつかのものを変更しなければならなかった - edit3セクションをチェックする//編集 - 私が行を変更したことを意味する – andrewpo

+0

もう一度感謝しています – andrewpo

-2

:私は、はるかに容易かつ簡単である2つのアレイを組み合わせ、ほとんどの最も簡単な方法は、最初の配列にXMLを変更していると思います

<?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

。最後に配列をxmlに戻します。 2つのXMLファイルを直接結合したい場合に役立ちます。子ノードを追加する位置は、どのキーであるかを考慮する必要があります。

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:DOMを使用してみてください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); 
関連する問題