我有这个XML:
<Meals>
<Meal>
<Food course="starter">Soup</Food>
<Food course="mains">Fish</Food>
<Food course="dessert">Ice cream</Food>
</Meal>
<Meal>
<Food course="starter">Soup</Food>
<Food course="mains">Chicken</Food>
<Food course="dessert">Cheese</Food>
</Meal>
<Meal>
<Food course="starter">Melon</Food>
<Food course="mains">lamb</Food>
<Food course="dessert">Ice cream</Food>
</Meal>
</Meals>
这个XPath表达式:
//Food[@course='dessert' and text() = 'Ice cream']
找到冰淇淋的每道甜点。我想在每个匹配的元素之后添加一个新元素,如下所示:
<Meals>
<Meal>
<Food course="starter">Soup</Food>
<Food course="mains">Fish</Food>
<Food course="dessert">Ice cream</Food>
<Review>enjoyed</Food>
</Meal>
<Meal>
<Food course="starter">Soup</Food>
<Food course="mains">Chicken</Food>
<Food course="dessert">Cheese</Food>
</Meal>
<Meal>
<Food course="starter">Melon</Food>
<Food course="mains">lamb</Food>
<Food course="dessert">Ice cream</Food>
<Review>enjoyed</Food>
</Meal>
</Meals>
鉴于XPath表达式,我该如何在C#中执行此操作?表达式可能会更改(例如,改为选择电源),并且XML的结构也可能会有所不同。无论如何,都必须在每个匹配的元素之后插入一个新元素。
我知道XElement上有一个AddAfterSelf方法,但是我不知道如何在XPath表达式可能返回的XElements集合上使用该方法。
答案 0 :(得分:1)
LINQ到XML
var doc = XDocument.Parse("filepath");
var enjoyedMeals =
doc.Descendants("Meal")
.Where(meal => meal.Elements.Any(food => food.Attribute("course").Value == "desert"));
foreach (var meal in enjoyedMeals)
{
var review = new XElement("Review", "enjoyed");
meal.Elements.Add(review);
}
doc.ToString(); // contains <Review> elements
答案 1 :(得分:1)
这很简单,但是我需要@Fabio提醒,需要进行foreach操作:
foreach (var element in foodXml.XPathSelectElements(xpathExpression))
{
element.AddAfterSelf(new XElement($"Review", "enjoyed"));
}
foodXml现在在匹配元素之后有一个额外的欣赏元素
答案 2 :(得分:0)
这个XPath表达式:
//Food[@course='dessert' and text() = 'Ice cream']
这会发现每餐餐点都有冰淇淋甜点。我想要 在每个匹配元素之后添加一个新元素,如下所示:
该表达是错误的。您需要:
/Meals/Meal[Food[@course = 'dessert'] = 'Ice cream']