我有两个
XML文件,我想将这两个文件合并为一个.
但是怎么样?我已经尝试了很多,但没有任何帮助.
正如您所看到的,合并后的XML如果来自第一个XML,则会从第二个属性中删除该文本.
第二个元素必须由第一个属性的Id / Name / whatevername命令.
第三,如果XML 2中不存在节点,则必须在与XML 1中相同的位置创建节点.
但是怎么样?我已经尝试了很多,但没有任何帮助.
正如您所看到的,合并后的XML如果来自第一个XML,则会从第二个属性中删除该文本.
第二个元素必须由第一个属性的Id / Name / whatevername命令.
第三,如果XML 2中不存在节点,则必须在与XML 1中相同的位置创建节点.
这里显示的XML文件只是整个XML的一个片段,还有更多的属性名称.
我怎么能用C#做到这一点?
XML 1
<APPLICATION> <AC> <CLASS Name="Hello1" Capt="do1"/> <CLASS Name="Hello2" Capt="do2"/> <CLASS Name="Hello5" Capt="do5"/> <CLASS Name="Hello8" Capt="do8"/> </AC> <BO> <ITEM Id="1" DefaultValue="name1"/> <ITEM Id="3" DefaultValue="name3"/> <ITEM Id="11" DefaultValue="name11"/> <ITEM Id="12" DefaultValue="name12"> <VAL> <REASON Id="Job1" SecondOne="Hallo"/> </VAL> </ITEM> </BO> <POP Id="Green" Value="Monster"/> <POP Id="Blue" Value="Doggie"/>
XML 2
<APPLICATION> <AC> <CLASS Name="Hello1" Capt="dodo1"/> <CLASS Name="Hello2" Capt="dodo2"/> <CLASS Name="Hello3" Capt="dodo3"/> <CLASS Name="Hello9" Capt="dodo9"/> </AC> <CARS Wheel="Fore" Default="45x255xZ"/> <CARS Wheel="BACK" Default="45x255xZ"/> <CARS Wheel="SPARE" Default="45x255xZ"/> <BO> <ITEM Id="1" DefaultValue="namename1"/> <ITEM Id="3" DefaultValue=""/> <ITEM Id="9" DefaultValue="name11"/> <ITEM Id="10" DefaultValue="name12"> <VAL> <REASON Id="Job1" SecondOne="Hallo"/> </VAL> </ITEM> </BO>
合并后XML应如下所示:
<APPLICATION> <AC> <CLASS Name="Hello1" Capt="dodo1"/> <CLASS Name="Hello2" Capt="dodo2"/> <CLASS Name="Hello3" Capt="dodo3"/> <CLASS Name="Hello5" Capt=""/> <CLASS Name="Hello8" Capt=""/> <CLASS Name="Hello9" Capt="dodo9"/> </AC> <CARS Wheel="Fore" Default="45x255xZ"/> <CARS Wheel="BACK" Default="45x255xZ"/> <CARS Wheel="SPARE" Default="45x255xZ"/> <BO> <ITEM Id="1" DefaultValue="namename1"/> <ITEM Id="3" DefaultValue=""/> <ITEM Id="9" DefaultValue="name11"/> <ITEM Id="10" DefaultValue="name12"> <VAL> <REASON Id="Job1" SecondOne="Hallo"/> </VAL> </ITEM> <ITEM Id="11" DefaultValue=""/> <ITEM Id="12" DefaultValue=""> <VAL> <REASON Id="Job1" SecondOne=""/> </VAL> </ITEM> </BO> <POP Id="Green" Value=""/> <POP Id="Blue" Value=""/>
所有答案都是Thanx,但我仍有问题,我不知道标记名是什么,所以我不能硬编码标签.
我只需要举例说明它的样子.但是下次我获取XML文件时,上面的标签可能完全不同.这就是问题所在.所以我不能说新的XElement(“BO”,boChildren),因为下次这个标签不再存在了.
或者我不能硬编码==> var cars = xDocuments.SelectMany(x => x.Root.Elements(“CARS”)).Merge();因为下次我得到我的XML文件“CARS”不再存在.
解决方法
我认为你可以用Linq to XML做到这一点.为每个段(AC,BO,CARS,POP)创建单独的查询,将它们连接在一起,然后将它们放在一个新文档中.
这是一个让你开始的小片段:
using System.Collections.Generic; using System.Linq; using System.Xml.Linq; namespace XML_Merge { class Program { static void Main(string[] args) { // load two xdocs var x1 = XDocument.Load("x1.xml"); var x2 = XDocument.Load("x2.xml"); // select the CLASS nodes from each var c1 = x1.Descendants("AC").First().Descendants("CLASS"); var c2 = x2.Descendants("AC").First().Descendants("CLASS"); // this one gives the distinct union of the two,you can put that into the result xdoc. var cComb = c1 .Union(c2) .Distinct(new ClassComparer()) // this uses the IEqualityComparer from below .OrderBy(c => c.Attribute("Name").Value); } } // This is required for Union to work. (Also Intersect etc) class ClassComparer : IEqualityComparer<XElement> { public bool Equals(XElement x,XElement y) { return x.Attribute("Name").Value == y.Attribute("Name").Value; } public int GetHashCode(XElement obj) { return obj.Attribute("Name").Value.GetHashCode(); } } }
只需重复源文档中的其他节点,然后将它们放在一起.
祝好运,
格特 – 扬