开发者

Linq to XML and multiple transforms

开发者 https://www.devze.com 2022-12-09 02:13 出处:网络
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 t

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

0

精彩评论

暂无评论...
验证码 换一张
取 消