Reputation: 29155
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 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?
Upvotes: 1
Views: 158
Reputation: 29155
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)
Upvotes: 1