我有两个xml文件,它们都具有相同的模式,我想合并到一个xml文件中.是否有捷径可寻?
例如,
<Root>
<LeafA>
<Item1 />
<Item2 />
</LeafA>
<LeafB>
<Item1 />
<Item2 />
</LeafB>
</Root>
Run Code Online (Sandbox Code Playgroud)
+
<Root>
<LeafA>
<Item3 />
<Item4 />
</LeafA>
<LeafB>
<Item3 />
<Item4 />
</LeafB>
</Root>
Run Code Online (Sandbox Code Playgroud)
=包含新文件
<Root>
<LeafA>
<Item1 />
<Item2 />
<Item3 />
<Item4 />
</LeafA>
<LeafB>
<Item1 />
<Item2 />
<Item3 />
<Item4 />
</LeafB>
</Root>
Run Code Online (Sandbox Code Playgroud)
DK.*_*DK. 11
"自动XML合并"听起来像是一个相对简单的要求,但是当你深入研究所有细节时,它会变得非常复杂.与c#或XSLT合并对于更具体的任务将更容易,例如在EF模型的答案中.使用工具来协助手动合并也可以是一个选项(参见这个问题).
有关参考(并提供复杂性的概念),这里是Java世界的一个开源示例:XML合并变得简单
回到原来的问题.任务规范中几乎没有大的灰色区域:当2个元素应该被认为是等价的(具有相同的名称,匹配选定的或所有的属性,或者在父元素中也具有相同的位置); 原始或合并的XML有多个等价元素等时如何处理情况
下面的代码假设
.
// determine which elements we consider the same
//
private static bool AreEquivalent(XElement a, XElement b)
{
if(a.Name != b.Name) return false;
if(!a.HasAttributes && !b.HasAttributes) return true;
if(!a.HasAttributes || !b.HasAttributes) return false;
if(a.Attributes().Count() != b.Attributes().Count()) return false;
return a.Attributes().All(attA => b.Attributes(attA.Name)
.Count(attB => attB.Value == attA.Value) != 0);
}
// Merge "merged" document B into "source" A
//
private static void MergeElements(XElement parentA, XElement parentB)
{
// merge per-element content from parentB into parentA
//
foreach (XElement childB in parentB.DescendantNodes())
{
// merge childB with first equivalent childA
// equivalent childB1, childB2,.. will be combined
//
bool isMatchFound = false;
foreach (XElement childA in parentA.Descendants())
{
if (AreEquivalent(childA, childB))
{
MergeElements(childA, childB);
isMatchFound = true;
break;
}
}
// if there is no equivalent childA, add childB into parentA
//
if (!isMatchFound) parentA.Add(childB);
}
}
Run Code Online (Sandbox Code Playgroud)
它将使用原始XML片段产生所需的结果,但如果输入XML更复杂并且具有重复元素,则结果将更加有趣:
public static void Test()
{
var a = XDocument.Parse(@"
<Root>
<LeafA>
<Item1 />
<Item2 />
<SubLeaf><X/></SubLeaf>
</LeafA>
<LeafB>
<Item1 />
<Item2 />
</LeafB>
</Root>");
var b = XDocument.Parse(@"
<Root>
<LeafB>
<Item5 />
<Item1 />
<Item6 />
</LeafB>
<LeafA Name=""X"">
<Item3 />
</LeafA>
<LeafA>
<Item3 />
</LeafA>
<LeafA>
<SubLeaf><Y/></SubLeaf>
</LeafA>
</Root>");
MergeElements(a.Root, b.Root);
Console.WriteLine("Merged document:\n{0}", a.Root);
}
Run Code Online (Sandbox Code Playgroud)
这里的合并文档显示了文档B中的等效元素是如何组合在一起的:
<Root>
<LeafA>
<Item1 />
<Item2 />
<SubLeaf>
<X />
<Y />
</SubLeaf>
<Item3 />
</LeafA>
<LeafB>
<Item1 />
<Item2 />
<Item5 />
<Item6 />
</LeafB>
<LeafA Name="X">
<Item3 />
</LeafA>
</Root>
Run Code Online (Sandbox Code Playgroud)