I'm having trouble groking something in Linq - maybe someone can give me some tips.
I have XML that I need to transform to new XML. The problem with this is that it is I need several iterations of transformation to get it right.
The source would look something like this:
<Meals>
<ketchup/>
<steak/>
<mustard/>
<thigh/>
<fillet/>
<penne/>
<drumstick/>
<steak/>
<ketchup/>
<fillet/>
<fillet/>
<macaroni/>
<drumstick/>
<thigh/>
<ketchup/>
<thigh/>
<fillet/>
</Meals>
What I'd like this to end up being开发者_如何学Python is:
<Meals>
<Meal>
<ketchup/>
<steak/>
<mustard/>
<thigh/>
</Meal>
<Meal>
<fillet/>
<penne/>
<drumstick/>
</Meal >
<Meal>
<steak/>
<ketchup/>
</Meal>
<Meal>
<fillet/>
</Meal>
<Meal>
<fillet/>
<macaroni/>
<drumstick/>
</Meal>
<Meal>
<thigh/>
<ketchup/>
</Meal>
<Meal>
<thigh/>
<fillet/>
</Meal>
</Meals>
The logic here is that:
<steak>
and<fillet>
are beef meats - anything that occurs before or after them that is not a beef meat part of the meal so long as it's not already part of another meal. If beef meat occurs after a beef meat, a new meal is created at the element of the new beef meat.<thigh>
and<drumstick>
are chicken meats - anything that occurs before or after them that is not a chicken meat is part of the meal so long as it's not already part of another meal. If chicken meat occurs after a chicken meat, a new meal is created at the element of the new chicken meat.<macaroni>
and<penne>
are pastas anything that occurs before or after them that is not a pasta is part of the meal so long as it's not already part of another meal. If pasta occurs after a pasta, a new meal is created at the element of the new pasta.<ketchup>
and<mustard>
are condiments - they can be part of any meal.
I've started with ElementsAfterSelf and ElementsBeforeSelf and TakeWhile, but am running into walls with my understanding of how to perform the above. I'm using VB.NET and Linq, but can read C#.
Any thoughts or pointers?
Got a good answer from another forum and here's the final:
Dim meals As XElement = <Meals>
<ketchup/>
<steak/>
<mustard/>
<thigh/>
<fillet/>
<macaroni/>
<drumstick/>
<thigh/>
<ketchup/>
<thigh/>
<fillet/>
</Meals>
Dim newMeals As XElement = <Meals/>
Dim meal As XElement = <Meal/>
Dim hasBeef As Boolean
Dim hasChicken As Boolean
For Each m In meals.Descendants()
Select Case m.Name
Case Is = "steak", "fillet"
If hasBeef Then
newMeals.Add(meal)
meal = <Meal/>
hasChicken = False
Else
hasBeef = True
End If
meal.Add(m)
Case Is = "drumstick", "thigh"
If hasChicken Then
newMeals.Add(meal)
meal = <Meal/>
hasBeef = False
Else
hasChicken = True
End If
meal.Add(m)
Case Else
meal.Add(m)
End Select
Next
newMeals.Add(meal)
You might find LINQPad useful. I'd give your problem a go, but I'm not clear on the combination logic you specified, as it doesn't match up to the example as I understand it (e.g., why isn't mustard in every meal?)
精彩评论