xml1.xml
<app>
<bbb>
<jjj>test1</jjj>
</bbb>
<bbb>
<jjj>test2</jjj>
</bbb>
</app>
xml2.xml
文件2 xml2.xml
<app>
<bbb>
<jjj>test2</jjj>
</bbb>
<bbb>
<jjj>test3</jjj>
</bbb>
<bbb>
<jjj>test4</jjj>
</bbb>
</app>
我可以将 2 个文件合并为 1 个文件吗?
<app>
<bbb>
<jjj>test1</jjj>
</bbb>
<bbb>
<jjj>test2</jjj>
</bbb>
<bbb>
<jjj>test3</jjj>
</bbb>
<bbb>
<jjj>test4</jjj>
</bbb>
</app>
答案1
改编自https://stackoverflow.com/questions/10163675/merge-xml-files-in-php
$doc1 = new DOMDocument();
$doc1->load('xml1.xml');
$doc2 = new DOMDocument();
$doc2->load('xml2.xml');
// get 'app' element of document 1
$app1 = $doc1->getElementsByTagName('app')->item(0);
// iterate over 'bbb' elements of document 2
$items2 = $doc2->getElementsByTagName('bbb');
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 'app' element
$app1 ->appendChild($item1);
}
$doc1->save('merged.xml');
答案2
看起来你可以做一个合并 sort
并修剪它。基本上sort
只是假设您知道自己在做什么,并对两个或多个输入运行一次传递,并在字典排序顺序收敛时将它们交错排列。
以下是 GNU -m
ergesort
为您的示例打印的内容:
<app>
<app>
<bbb>
<bbb>
<jjj>test1</jjj>
</bbb>
<bbb>
<jjj>test2</jjj>
</bbb>
<bbb>
<jjj>test2</jjj>
</bbb>
</app>
<jjj>test3</jjj>
</bbb>
<bbb>
<jjj>test4</jjj>
</bbb>
</app>
所以至少现在它全部折叠起来了,但是,就像我说的,你仍然需要修剪它。该sed
脚本将为您的示例执行此操作:
sort -m /tmp/xml[12] |
sed -ne:n -e'$!s|/a..> *$|bbb>|;$p' \
-e'\|^[^>]*b.*\n|{N;P;D;}' \
-eN -e's|\(.*\)\n\(.*\n\)* *\1 *$|\1|' \
-e's|\n|&|3;tD' -ebn -e:D -eP\;D
它只是确保在输入时至少堆叠三行,并在第一行不是标签时将堆栈中的第一行与最后一行进行比较<bbb>
。
<app>
<bbb>
<jjj>test1</jjj>
</bbb>
<bbb>
<jjj>test2</jjj>
</bbb>
<bbb>
<jjj>test3</jjj>
</bbb>
<bbb>
<jjj>test4</jjj>
</bbb>
</app>
答案3
你不能使用“shell”linux - 来处理 XML,你真的需要一个 XML 解析器。
然而,有很多脚本工具确实有选项 - 我个人最喜欢的perl
是XML::Twig
图书馆。 (这在 Unix 包管理器中非常常见,尽管不是“核心”的一部分)。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
#load both
my $first = XML::Twig->new->parsefile('xml1.xml');
my $second = XML::Twig->new->parsefile('xml2.xml');
#iterate bbb elements in second file
foreach my $bbb ( $second->get_xpath('//bbb') ) {
#extract 'text' of jjj element (of this bbb element)
my $jjj = $bbb->first_child_text('jjj');
#use xpath query to check it doesn't exist first.
if ( not $first->get_xpath("//bbb/jjj[string()='$jjj']") ) {
print $jjj, " not in first, splicing\n";
#cut/paste (note - done in memory, so original file isn't altered)
$bbb->move( 'last_child', $first->root );
}
}
#set output formatting - can do some odd things with particularly strange XMl.
$first->set_pretty_print('indented_a');
$first->print;
## if you want to save it:
open( my $output, '>', "combined.xml" ) or die $!;
print {$output} $first->sprint;
close($output);