C# 合并Xml文件
我需要合并一个结构未知的xml。请求是层次结构不会更改:C# 合并Xml文件,c#,xml,merge,C#,Xml,Merge,我需要合并一个结构未知的xml。请求是层次结构不会更改: XDocument xDoc1 = XDocument.Parse(@"<Root> <LeafA> <a>item1</a>
XDocument xDoc1 = XDocument.Parse(@"<Root>
<LeafA>
<a>item1</a>
</LeafA>
<LeafA>
<b>item3</b>
</LeafA>
</Root>");
XDocument xDoc2 = XDocument.Parse(@"<Root>
<LeafA>
<a>item2</a>
</LeafA>
<LeafA>
<b>item4</b>
</LeafA>
</Root>");
Merge(xDoc1.Root, xDoc2.Root);
这给了我
<Root>
<LeafA>
<a>item1</a>
<b>item4</b>
</LeafA>
<LeafA>
<b>item3</b>
</LeafA>
</Root>
项目1
项目4
项目3
但必须如此
<Root>
<LeafA>
<a>item1</a>
<a>item2</a>
</LeafA>
<LeafA>
<b>item3</b>
<b>item4</b>
</LeafA>
</Root>
项目1
项目2
项目3
项目4
这解决了我的问题:
public static void Merge(XElement left, XElement right)
{
foreach (XElement node in right.Elements())
{
int num = MergeXml.NodeWithSameNameAtSameHierarchyLevel(left, node);
if (num == 0)
{
left.Add(node);
}
else
{
if (MergeXml.IsFirstIteration(left, right) && !node.HasElements)
{
left.Add(node);
}
else
{
if (num == 1)
{
MergeXml.CheckDescandants(left, node);
}
else
{
if (node.Descendants().Any<XElement>() && node.Descendants().First<XElement>().Name.LocalName.Equals(node.Name.LocalName))
{
MergeXml.CheckDescandants(left, node);
}
else
{
int num2 = node.ElementsBeforeSelf().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName));
foreach (XElement current in node.Elements())
{
if (current.HasElements)
{
if (MergeXml.ItemNodeExistInLeftFile(left, node, num2) || MergeXml.ItemNodeDescandandsDontHaveAnyElements(current))
{
MergeXml.CheckDescandants(left, current, num2);
}
else
{
(
from x in left.Elements()
where x.Name.LocalName.Equals(node.Name.LocalName)
select x).ElementAt(num2).Add(current);
}
}
else
{
(
from x in left.Elements()
where x.Name.LocalName.Equals(node.Name.LocalName)
select x).ElementAt(num2).Add(current);
}
}
}
}
}
}
}
}
public static XDocument MergeXmlFiles(List<XDocument> docs)
{
MergeXml.Merge(docs[0].Root, docs[1].Root);
MergeXml.Merge(docs[0].Root, docs[2].Root);
return docs[0];
}
private static void CheckDescandants(XElement left, XElement node)
{
if (node.Descendants().Count((XElement x) => x.HasElements) > 0)
{
MergeXml.Merge(left.Element(node.Name.LocalName), node);
return;
}
if (left.Element(node.Name.LocalName) != null)
{
if (node.HasElements)
{
left.Element(node.Name.LocalName).Add(node.Descendants());
return;
}
left.Element(node.Name.LocalName).Add(node);
return;
}
else
{
if (node.HasElements)
{
left.Add(node.Descendants());
return;
}
left.Add(node);
return;
}
}
private static void CheckDescandants(XElement left, XElement node, int recursivCallIndex)
{
if (node.Descendants().Count((XElement x) => x.HasElements) > 0)
{
MergeXml.Merge(left.Elements().ElementAt(recursivCallIndex).Element(node.Name.LocalName), node);
return;
}
IEnumerable<XElement> source =
from x in left.Elements().ElementAt(recursivCallIndex).Descendants()
where x.Name == node.Name
select x;
if (source.Count<XElement>() > 0)
{
source.ElementAt(0).Add(node.Descendants());
return;
}
left.Elements().ElementAt(recursivCallIndex).Add(node);
}
private static bool IsFirstIteration(XElement left, XElement right)
{
return left.Parent == null && right.Parent == null;
}
private static bool ItemNodeDescandandsDontHaveAnyElements(XElement item)
{
return item.Descendants().Count((XElement x) => x.HasElements) == 0;
}
private static bool ItemNodeExistInLeftFile(XElement left, XElement node, int positionNodeInXmlIndex)
{
return left.Elements().ElementAt(positionNodeInXmlIndex).Element(node.Name.LocalName) != null;
}
private static int NodeWithSameNameAtSameHierarchyLevel(XElement left, XElement node)
{
if (!left.Descendants().Any<XElement>())
{
return 0;
}
if (left.Descendants().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName)) == 0)
{
return 0;
}
return left.Descendants().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName) && DivideXml.HasSameParentName(x, node));
}
publicstaticvoidmerge(元素左、元素右)
{
foreach(右侧的XElement节点。Elements())
{
int num=MergeXml.nodeWithSamenateSamehierArchylevel(左,节点);
如果(num==0)
{
左。添加(节点);
}
其他的
{
if(MergeXml.IsFirstIteration(左、右)&&&!node.HasElements)
{
左。添加(节点);
}
其他的
{
如果(num==1)
{
checkdescands(左,节点);
}
其他的
{
if(node.subjects().Any()&&node.subjects().First().Name.LocalName.Equals(node.Name.LocalName))
{
checkdescands(左,节点);
}
其他的
{
int num2=node.ElementsBeforeSelf().Count((XElement x)=>x.Name.LocalName.Equals(node.Name.LocalName));
foreach(节点.Elements()中的当前元素)
{
if(当前的.HasElements)
{
if(MergeXml.ItemNodeExistInLeftFile(左,节点,num2)| | MergeXml.itemnodescandsdonSaveanyElements(当前))
{
MergeXml.CheckDescandants(左、当前、num2);
}
其他的
{
(
从左x开始。元素()
其中x.Name.LocalName.Equals(node.Name.LocalName)
选择x).ElementAt(num2).Add(当前);
}
}
其他的
{
(
从左x开始。元素()
其中x.Name.LocalName.Equals(node.Name.LocalName)
选择x).ElementAt(num2).Add(当前);
}
}
}
}
}
}
}
}
公共静态XDocument合并XML文件(列表文档)
{
MergeXml.Merge(文档[0]。根,文档[1]。根);
MergeXml.Merge(文档[0]。根,文档[2]。根);
退货单据[0];
}
专用静态无效检查定义标准(XElement左侧,XElement节点)
{
if(node.subjects().Count((XElement x)=>x.HasElements)>0)
{
MergeXml.Merge(left.Element(node.Name.LocalName),node);
返回;
}
if(left.Element(node.Name.LocalName)!=null)
{
if(node.HasElements)
{
元素(node.Name.LocalName).Add(node.subjects());
返回;
}
元素(node.Name.LocalName).Add(node);
返回;
}
其他的
{
if(node.HasElements)
{
添加(node.subjects());
返回;
}
左。添加(节点);
返回;
}
}
私有静态void checkdescands(XElement左、XElement节点、int recursivCallIndex)
{
if(node.subjects().Count((XElement x)=>x.HasElements)>0)
{
MergeXml.Merge(left.Elements().ElementAt(recursivCallIndex).Element(node.Name.LocalName),node);
返回;
}
IEnumerable源=
从left.Elements().ElementAt(recursivCallIndex.substands()中的x开始
其中x.Name==node.Name
选择x;
if(source.Count()>0)
{
source.ElementAt(0).Add(node.subjects());
返回;
}
left.Elements().ElementAt(递归调用索引).Add(节点);
}
私有静态布尔值IsFirstIteration(XElement左、XElement右)
{
返回left.Parent==null&&right.Parent==null;
}
私有静态布尔项NodeDeScandsDaveAnyElements(XElement项)
{
返回item.subjects().Count((XElement x)=>x.HasElements)==0;
}
私有静态bool项nodeexistinleftfile(XElement左、XElement节点、int-positionNodeInXmlIndex)
{
返回left.Elements().ElementAt(positionNodeInXmlIndex).Element(node.Name.LocalName)!=null;
}
私有静态int节点WithSameNameAtSameHierarchylevel(XElement左,XElement节点)
{
如果(!left.subjects().Any())
{
返回0;
}
if(left.subjections().Count((XElement x)=>x.Name.LocalName.Equals(node.Name.LocalName))==0)
{
返回0;
}
返回left.subjects().Count((XElement x)=>x.Name.LocalName.Equals(node.Name.LocalName)&&DivideXml.HasSameParentName(x,node));
}
您是否尝试过解析和重建新的XML?是的,这对我没有帮助。我想您无法给出我的答案。我会帮你删除它。
public static void Merge(XElement left, XElement right)
{
foreach (XElement node in right.Elements())
{
int num = MergeXml.NodeWithSameNameAtSameHierarchyLevel(left, node);
if (num == 0)
{
left.Add(node);
}
else
{
if (MergeXml.IsFirstIteration(left, right) && !node.HasElements)
{
left.Add(node);
}
else
{
if (num == 1)
{
MergeXml.CheckDescandants(left, node);
}
else
{
if (node.Descendants().Any<XElement>() && node.Descendants().First<XElement>().Name.LocalName.Equals(node.Name.LocalName))
{
MergeXml.CheckDescandants(left, node);
}
else
{
int num2 = node.ElementsBeforeSelf().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName));
foreach (XElement current in node.Elements())
{
if (current.HasElements)
{
if (MergeXml.ItemNodeExistInLeftFile(left, node, num2) || MergeXml.ItemNodeDescandandsDontHaveAnyElements(current))
{
MergeXml.CheckDescandants(left, current, num2);
}
else
{
(
from x in left.Elements()
where x.Name.LocalName.Equals(node.Name.LocalName)
select x).ElementAt(num2).Add(current);
}
}
else
{
(
from x in left.Elements()
where x.Name.LocalName.Equals(node.Name.LocalName)
select x).ElementAt(num2).Add(current);
}
}
}
}
}
}
}
}
public static XDocument MergeXmlFiles(List<XDocument> docs)
{
MergeXml.Merge(docs[0].Root, docs[1].Root);
MergeXml.Merge(docs[0].Root, docs[2].Root);
return docs[0];
}
private static void CheckDescandants(XElement left, XElement node)
{
if (node.Descendants().Count((XElement x) => x.HasElements) > 0)
{
MergeXml.Merge(left.Element(node.Name.LocalName), node);
return;
}
if (left.Element(node.Name.LocalName) != null)
{
if (node.HasElements)
{
left.Element(node.Name.LocalName).Add(node.Descendants());
return;
}
left.Element(node.Name.LocalName).Add(node);
return;
}
else
{
if (node.HasElements)
{
left.Add(node.Descendants());
return;
}
left.Add(node);
return;
}
}
private static void CheckDescandants(XElement left, XElement node, int recursivCallIndex)
{
if (node.Descendants().Count((XElement x) => x.HasElements) > 0)
{
MergeXml.Merge(left.Elements().ElementAt(recursivCallIndex).Element(node.Name.LocalName), node);
return;
}
IEnumerable<XElement> source =
from x in left.Elements().ElementAt(recursivCallIndex).Descendants()
where x.Name == node.Name
select x;
if (source.Count<XElement>() > 0)
{
source.ElementAt(0).Add(node.Descendants());
return;
}
left.Elements().ElementAt(recursivCallIndex).Add(node);
}
private static bool IsFirstIteration(XElement left, XElement right)
{
return left.Parent == null && right.Parent == null;
}
private static bool ItemNodeDescandandsDontHaveAnyElements(XElement item)
{
return item.Descendants().Count((XElement x) => x.HasElements) == 0;
}
private static bool ItemNodeExistInLeftFile(XElement left, XElement node, int positionNodeInXmlIndex)
{
return left.Elements().ElementAt(positionNodeInXmlIndex).Element(node.Name.LocalName) != null;
}
private static int NodeWithSameNameAtSameHierarchyLevel(XElement left, XElement node)
{
if (!left.Descendants().Any<XElement>())
{
return 0;
}
if (left.Descendants().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName)) == 0)
{
return 0;
}
return left.Descendants().Count((XElement x) => x.Name.LocalName.Equals(node.Name.LocalName) && DivideXml.HasSameParentName(x, node));
}