Linq to XML et plusieurs transformations
-
06-07-2019 - |
Question
J'ai du mal à faire quelque chose à Linq - peut-être que quelqu'un pourra me donner des conseils.
J'ai XML que je dois transformer en nouveau XML. Le problème, c’est que j’ai besoin de plusieurs itérations de transformation pour réussir.
La source ressemblerait à quelque chose comme ceci:
<Meals>
<ketchup/>
<steak/>
<mustard/>
<thigh/>
<fillet/>
<penne/>
<drumstick/>
<steak/>
<ketchup/>
<fillet/>
<fillet/>
<macaroni/>
<drumstick/>
<thigh/>
<ketchup/>
<thigh/>
<fillet/>
</Meals>
Ce que j'aimerais que cela finisse par être:
<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>
La logique est la suivante:
-
<steak>
et<fillet>
sont du boeuf viandes - tout ce qui se passe avant ou après eux ce n'est pas une viande de boeuf une partie du repas tant qu’il ne fait pas déjà partie d’un autre repas. Si la viande de bœuf survient après une viande de bœuf, un nouveau repas est créé dans l'élément de la nouvelle viande de bœuf. -
<thigh>
et<drumstick>
sont viande de poulet - tout ce qui se produit avant ou après eux, ce n'est pas la viande de poulet fait partie du repas tant qu'elle ne fait pas déjà partie d'un autre repas. Si la viande de poulet est produite après une viande de poulet, un nouveau repas est créé dans l'élément de la nouvelle viande de poulet. -
<macaroni>
et<penne>
sont des pâtes alimentaires, tout ce qui se produit avant ou après les pâtes ne une partie du repas tant qu’il ne fait pas déjà partie d’un autre repas. Si les pâtes sont produites après les pâtes, un nouveau repas est créé à l’élément des nouvelles pâtes. -
<ketchup>
et<mustard>
sont condiments - ils peuvent faire partie de tout repas.
J'ai commencé avec ElementsAfterSelf et ElementsBeforeSelf et TakeWhile, mais je me heurte aux murs avec ma compréhension de la manière de procéder. J'utilise VB.NET et Linq, mais je peux lire C #.
Avez-vous des idées ou des indications?
La solution
Vous avez une bonne réponse d'un autre forum et voici la finale:
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)
Autres conseils
Vous pourriez trouver LINQPad utile. Je tenterais votre problème, mais je ne comprends pas bien la logique de combinaison que vous avez spécifiée, car elle ne correspond pas à l'exemple tel que je le comprends (par exemple, pourquoi la moutarde n'est-elle pas à chaque repas?)