C# 如何合并两个XDocuments以删除重复项
我有两个XML文件(*.resx文件),我正试图将它们合并到一个文件中以删除重复项,但无法这样做。我尝试了以下方法,但没有成功:C# 如何合并两个XDocuments以删除重复项,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我有两个XML文件(*.resx文件),我正试图将它们合并到一个文件中以删除重复项,但无法这样做。我尝试了以下方法,但没有成功: var resource1 = XDocument.Load("C:\\Resources.resx"); var resource2 = XDocument.Load("C:\\Resources2.resx"); // This results in a file with all the
var resource1 = XDocument.Load("C:\\Resources.resx");
var resource2 = XDocument.Load("C:\\Resources2.resx");
// This results in a file with all the nodes from the second file included inside
// the root element of the first file to form a properly formatted, concatenated file.
resource1.Descendants().FirstOrDefault().Add(resource2.Descendants().FirstOrDefault().Nodes());
var nodeContent = new List<string>();
foreach (XElement node in resource1.Root.Elements())
{
if (nodeContent.Contains(node.ToString()))
resource1.Remove();
else
nodeContent.Add(node.ToString());
}
resource1.Save("C:\\FinalResources.resx");
var resource1=XDocument.Load(“C:\\Resources.resx”);
var resource2=XDocument.Load(“C:\\Resources2.resx”);
//这将生成一个包含第二个文件中所有节点的文件
//第一个文件的根元素,用于形成格式正确的连接文件。
resource1.subjects().FirstOrDefault().Add(resource2.subjects().FirstOrDefault().Nodes());
var nodeContent=新列表();
foreach(resource1.Root.Elements()中的XElement节点)
{
if(nodeContent.Contains(node.ToString()))
资源1.删除();
其他的
添加(node.ToString());
}
资源1.保存(“C:\\FinalResources.resx”);
在remove语句中,我得到了一个invalidoOperationException-“缺少父项”:
我做错什么了吗?资源1.删除();被调用两次,它所做的是删除根元素。因此,第二次不再存在要从中删除的根元素,从而引发异常。最直接的方法是:
var resource1 = XDocument.Load("C:\\Resources.resx");
var resource2 = XDocument.Load("C:\\Resources2.resx");
foreach (XElement node in resource2.Root.Elements())
{
if (resource1.Root.Contains(node)) continue;
resource1.Add(node);
}
resource1.Save("C:\\FinalResources.resx");
public static class XElementExtensions
{
public static bool Contains(this XElement root, XElement e)
{
//or w/e equality logic you need
return root.Elements().Any(x => x.ToString().Equals(e.ToString()));
}
}
这将只合并第一级条目tho。如果需要深度合并,则必须设置一个简单的递归(对子元素使用相同的循环)。您需要定义一个
EqualityComparer
,使您能够使用标准LINQ运算符
因此,作为一个简单的例子,我创建了以下内容:
public class ElementComparer : EqualityComparer<XElement>
{
public override int GetHashCode(XElement xe)
{
return xe.Name.GetHashCode() ^ xe.Value.GetHashCode();
}
public override bool Equals(XElement xe1, XElement xe2)
{
var @return = xe1.Name.Equals(xe2.Name);
if (@return)
{
@return = xe1.Value.Equals(xe2.Value);
}
return @return;
}
}
您应该定义什么是上下文中的“重复”。如何比较两个xml条目?通过
名称
属性?按标签名?按内容?如果仍然有人在寻找这个问题的答案,请看这里@Si8-什么东西不起作用?所有的代码都应该使用简单的复制粘贴。metge没有将第二个XDocument添加到第一个XDocument中,但我走了不同的路线。谢谢你,@Si8-我想你可能需要检查你的代码。我刚刚将代码复制/粘贴到一个新项目中,对我来说效果很好。如果可以的话,我想追查一下这个问题。谢谢。我的XDocument是一个Sharepoint ATOM提要,所以这可能就是为什么。@Si8-ATOM提要XML是否包含除默认名称空间之外的名称空间?
<xs>
<x>D</x>
<x>A</x>
<x>B</x>
</xs>
<xs>
<x>E</x>
<x>B</x>
<x>C</x>
</xs>
var xml1 = XDocument.Parse(@"<xs><x>D</x><x>A</x><x>B</x></xs>");
var xml2 = XDocument.Parse(@"<xs><x>E</x><x>B</x><x>C</x></xs>");
xml1.Root.Add(
xml2.Root.Elements("x")
.Except(xml1.Root.Elements("x"), new ElementComparer()));
<xs>
<x>D</x>
<x>A</x>
<x>B</x>
<x>E</x>
<x>C</x>
</xs>