我有2个文件1.xml
和2.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>
我想创建一个具有以下结构的新文件merged.xml
<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>
我该怎么做?你能解释一下这样做的方法吗?如何使用更多文件?谢谢
修改
我尝试了什么?
<?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
按照Torious的建议,我查看了DOMDocument手册并找到了一个例子:
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>
我无法正确使用此文件。我需要正确的结构,在这里我有一种文件粘贴到另一个文件中。我想&#34;粘贴&#34;只有项目不是所有标签。我应该改变什么?
EDIT3
这是一个答案 - 基于Torious的答案 - 只是根据我的需要调整 - 检查//编辑
$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 :(得分:17)
既然你付出了努力,我就编写了一些应该有用的东西。
请注意,这是未经测试的代码,但您明白了这一点。
由你决定将它变成漂亮的功能。确保你了解正在发生的事情;能够使用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);
}
答案 1 :(得分:0)
我认为最简单的方法是首先将XML更改为数组,将两个数组组合起来更容易和直接。最后将数组更改回xml。当您想直接组合两个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"));
}
}
}
用法:创建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);
答案 2 :(得分:-1)
怎么样:
<?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>');