求解答,多个xml文档合并的问题~~~~~~~~~~~~~~~~~~~~~~~
--------------------编程问答-------------------- 帮顶,, --------------------编程问答-------------------- 谢谢,求大神出现啊 --------------------编程问答--------------------可以的。
不过看你要合并的xml里面的元素会不会完全相同啊。如果相同你要怎么处理。
xml里面的层数会不会一样。这都要考虑。
起码要知道怎么个合并法。 --------------------编程问答-------------------- 回楼上的,元素不一定会完全相同,不相同的就追加
层数会不一样
就跟我列子上的那样 --------------------编程问答-------------------- 两个XML结构不一样,只能靠代码一一判断再合并 --------------------编程问答-------------------- 1.xml有的元素 2.xml不一定有。2.xml有的元素1不一定有。
这就麻烦,一个一个元素的判断。还要确定元素所在的层数。
一一逐个判断。再合并。
你多个要合并的xml文件可以规范一点吗。
--------------------编程问答-------------------- 2.xml再来一个<F V="100"/>或者 <C VA="50"/>
那怎么办,怎么个合并法。没有规律是没法合并的。
<?xml version="1.0" encoding="utf-8"?>--------------------编程问答-------------------- 用 linq2xml:(.net 3.5 以上可用)
<A>
<B>
<Item SystemTool="1" ToolType="2" Role="" JC="" AC="" DRC=""/>
<Item1 a="1" b="2"/>
</B>
<C VA="5"/>
<D VALUES="6"/>
<F V="100"/>
<E>
<G V="11"/>
<C VA="50"/>
</E>
</A>
--------------------编程问答-------------------- Merge 方法有点问题,修改下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Linq2Xml_MergeXml
{
class Program
{
static void Main(string[] args)
{
var xml1 = @"<?xml version=""1.0"" encoding=""utf-8""?>
<A>
<B>
<Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC=""3"" DRC=""""/>
</B>
<C VALUES=""4""/>
<E>
<F V=""10""/>
</E>
</A>";
Console.WriteLine(xml1);
Console.WriteLine("------------");
var xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?>
<A>
<B>
<Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC="""" DRC=""""/>
<Item1 a=""1"" b=""2""/>
</B>
<C VA=""5""/>
<D VALUES=""6""/>
<E>
<G V=""11""/>
</E>
</A>";
var xdoc1 = XDocument.Parse(xml1);
var xdoc2 = XDocument.Parse(xml2);
xdoc1.Merge(xdoc2);
Console.WriteLine(xdoc1.ToString());
Console.Read();
}
}
public static class XDocumentExtension
{
public static void Merge(this XDocument xdoc, XDocument mergedXdoc)
{
foreach (var node in xdoc.Descendants())
{
// Add nonexistence attributes
var target = mergedXdoc.Descendants(node.Name);
foreach (var att in target.Attributes())
{
// Check existence attributes by name not value
if (!node.Attributes().Select(t => t.Name.ToString())
.Contains(att.Name.ToString()))
node.Add(new XAttribute(att));
}
// Add nonexistence nodes
var targetChilds = target.Descendants();
var existsNodeNames = node.Descendants().Select(n => n.Name);
var noExistNodes = targetChilds.Where(t => !existsNodeNames.Contains(t.Name));
foreach (var newNode in noExistNodes)
node.LastNode.AddAfterSelf(newNode);
}
}
}
}
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 谢谢楼上的所有回答,我试试(JustACoder)的方法 --------------------编程问答-------------------- 回7楼,是元素不一定一样多,有可能出现你说的2.xml多一个<F/> ,然后需要的就是在3.xml里也出现这个<F/> --------------------编程问答-------------------- 有高人知道不是用linq的方法吗 --------------------编程问答-------------------- 我给你一个吧,要求:第一层根目录名字相同(例如都为A),并且合并不会出现名字或者属性的冲突(例如不会2个文件都存在C节点且都有属性 Type)
public static void Merge(this XDocument xdoc, XDocument mergedXdoc)
{
foreach (var node in xdoc.Descendants())
{
// Add nonexistence attributes
var target = mergedXdoc.Descendants(node.Name);
foreach (var att in target.Attributes())
{
// Check existence attributes by name not value
if (!node.Attributes().Select(t => t.Name.ToString())
.Contains(att.Name.ToString()))
node.Add(new XAttribute(att));
}
// Add nonexistence nodes
var targetChilds = target.Descendants();
var existsNodeNames = node.Descendants().Select(n => n.Name);
var noExistNodes = targetChilds.Where(t => !existsNodeNames.Contains(t.Name)
&& t.Parent.Name == node.Name);
foreach (var newNode in noExistNodes)
node.Add(newNode);
}
}
--------------------编程问答-------------------- xml有的元素 2.xml不一定有。2.xml有的元素1不一定有。
public static XmlDocument Merge(XmlDocument xd1, XmlDocument xd2)
{
XmlNode xnRoot1 = xd1.SelectSingleNode("/").ChildNodes[1];
XmlNode xnRoot2 = xd2.SelectSingleNode("/").ChildNodes[1];
string rootName = xnRoot2.Name;
for (int i = 0; i < xnRoot2.ChildNodes.Count; i++)
{
string nodeName = xnRoot2.ChildNodes[i].Name;
if (xnRoot1.SelectNodes(nodeName).Count == 0)
{
XmlNode xnTemp = xd1.ImportNode(xnRoot2.ChildNodes[i], true);
xnRoot1.AppendChild(xnTemp);
}
else
{
XmlNode xnDest = xnRoot1.SelectNodes(nodeName)[0];
for (int j = 0; j < xnRoot2.ChildNodes[i].ChildNodes.Count; j++)
{
XmlNode xnTemp = xd1.ImportNode(xnRoot2.ChildNodes[i].ChildNodes[j], true);
xnDest.AppendChild(xnTemp);
}
for (int k = 0; k < xnRoot2.ChildNodes[i].Attributes.Count; k++)
{
XmlAttribute xaTemp = xd1.CreateAttribute(xnRoot2.ChildNodes[i].Attributes[k].Name);
xaTemp.Value = xnRoot2.ChildNodes[i].Attributes[k].Value;
xnDest.Attributes.Append(xaTemp);
}
}
}
return xd1;
}
static void Main(string[] args)
{
var xml1 = @"<?xml version=""1.0"" encoding=""utf-8""?>
<A>
<B>
<Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC=""3"" DRC=""""/>
</B>
<C VALUES=""4""/>
<E>
<F V=""10""/>
</E>
</A>";
var xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?>
<A>
<B>
<Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC="""" DRC=""""/>
<Item1 a=""1"" b=""2""/>
</B>
<C VA=""5""/>
<D VALUES=""6""/>
<E>
<G V=""11""/>
</E>
</A>";
XmlDocument xdoc1 = new XmlDocument();
xdoc1.LoadXml(xml1);
XmlDocument xdoc2 = new XmlDocument();
xdoc2.LoadXml(xml2);
XmlDocument result = Merge(xdoc1, xdoc2);
}
这就麻烦,一个一个元素的判断。还要确定元素所在的层数。
一一逐个判断。再合并。 --------------------编程问答-------------------- 谢谢15楼的,我试试 --------------------编程问答--------------------
if (xnRoot1.SelectNodes(nodeName).Count == 0) 这句报错提示 “表达式的计算结果必须为节点集。”
补充:.NET技术 , C#