Todd Main
Todd Main

Reputation: 29155

Linq to XML and multiple transforms

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:

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

Answers (2)

Todd Main
Todd Main

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

Justin R.
Justin R.

Reputation: 24061

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?)

Upvotes: 0

Related Questions