合并两个XElement [英] Merge two XElements
问题描述
我不确定如何问这个问题,或者甚至不知道这个问题,但是我需要合并两个XElement,其中一个优先于另一个,以成为一个元素.
I'm not quite sure how to ask this, or if this even exists, but I have a need to merge two XElements with one taking precendence over the other, to become just one element.
这里的首选项是VB.NET和Linq,但是如果它能演示如何做到这一点,而无需我编写代码来手动分离并解析每个元素和属性,那么任何一种语言都将是有帮助的.
The preference here is VB.NET and Linq, but any language would be helpful if it demonstrates how to do this without me coding to manually pick apart and and resolve every single element and attribute.
例如,假设我有两个要素.让我为他们与众不同而感到幽默.
For example, let's say I have two elements. Humor me on them being as different as they are.
1.
<HockeyPlayer height="6.0" hand="left">
<Position>Center</Position>
<Idol>Gordie Howe</Idol>
</HockeyPlayer>
2.
<HockeyPlayer height="5.9" startinglineup="yes">
<Idol confirmed="yes">Wayne Gretzky</Idol>
</HockeyPlayer>
合并的结果将是
<HockeyPlayer height="6.0" hand="left" startinglineup="yes">
<Position>Center</Position>
<Idol confirmed="yes">Gordie Howe</Idol>
</HockeyPlayer>
请注意以下几点:#1的height
属性值取代了#2. hand
属性和值只是从#1复制而来的(在#2中不存在).复制了#2中的startinglineup
属性和值(在#1中不存在). #1中的Position
元素已被复制(在#2中不存在). #1中的Idol
元素值将覆盖#2,但是将复制#2的confirmed
属性(它在#1中不存在).
Notice a few things: the height
attribute value of #1 overrode #2. The hand
attribute and value was simply copied over from #1 (it doesn't exist in #2). The startinglineup
attribute and value from #2 was copied over (it doesn't exist in #1). The Position
element in #1 was copied over (it doesn't exist in #2). The Idol
element value in #1 overrides #2, but #2's attribute of confirmed
(it doesn't exist in #1) is copied over.
Net net,#1优先于#2,那里有冲突(意味着它们具有相同的元素和/或属性),没有冲突,它们都复制到最终结果中.
Net net, #1 takes precendence over #2 where there is a conflict (meaning both have the same elements and/or attributes) and where there is no conflict, they both copy to the final result.
我已经尝试过搜索,但是似乎什么也找不到,可能是因为我用来搜索的单词太笼统了.有什么想法或解决方案(特别是对于Linq)吗?
I've tried searching on this, but just can't seem to find anything, possibly because the words I'm using to search are too generic. Any thoughts or solutions (esp. for Linq)?
推荐答案
这是一个控制台应用程序,可产生您的问题中列出的结果.它使用递归来处理每个子元素.它不检查的一件事是出现在Elem2
中的子元素而不出现在Elem1
中,但是希望这将使您开始寻求解决方案.
Here's a console app that produces the result listed in your question. It uses recursion to process each sub element. The one thing it doesn't check for is child elements that appear in Elem2
that aren't in Elem1
, but hopefully this will get you started towards a solution.
我不确定我是否会说这是最好的解决方案,但是它确实有效.
I'm not sure if I would say this is the best possible solution, but it does work.
Module Module1
Function MergeElements(ByVal Elem1 As XElement, ByVal Elem2 As XElement) As XElement
If Elem2 Is Nothing Then
Return Elem1
End If
Dim result = New XElement(Elem1.Name)
For Each attr In Elem1.Attributes
result.Add(attr)
Next
Dim Elem1AttributeNames = From attr In Elem1.Attributes _
Select attr.Name
For Each attr In Elem2.Attributes
If Not Elem1AttributeNames.Contains(attr.Name) Then
result.Add(attr)
End If
Next
If Elem1.Elements().Count > 0 Then
For Each elem In Elem1.Elements
result.Add(MergeElements(elem, Elem2.Element(elem.Name)))
Next
Else
result.Value = Elem1.Value
End If
Return result
End Function
Sub Main()
Dim Elem1 = <HockeyPlayer height="6.0" hand="left">
<Position>Center</Position>
<Idol>Gordie Howe</Idol>
</HockeyPlayer>
Dim Elem2 = <HockeyPlayer height="5.9" startinglineup="yes">
<Idol confirmed="yes">Wayne Gretzky</Idol>
</HockeyPlayer>
Console.WriteLine(MergeElements(Elem1, Elem2))
Console.ReadLine()
End Sub
End Module
编辑:我刚刚注意到该功能缺少As XElement
.我真的很惊讶没有它就可以工作!我每天都在使用VB.NET,但是有些奇怪的地方我还是不太了解.
I just noticed that the function was missing As XElement
. I'm actually surprised that it worked without that! I work with VB.NET every day, but it has some quirks that I still don't totally understand.
这篇关于合并两个XElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!