在多个元素之后添加XML元素

时间:2019-03-15 11:41:21

标签: c# xml xpath

我有这个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集合上使用该方法。

3 个答案:

答案 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']