【问题标题】:Add XML Element after multiple elements在多个元素之后添加 XML 元素
【发布时间】:2019-03-15 11:41:20
【问题描述】:

我有这个 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# 中执行此操作?表达式可能会改变(例如选择 mains),并且 XML 的结构也可能会有所不同。无论如何,必须在每个匹配元素之后插入一个新元素。

我知道 XElement 上有一个 AddAfterSelf 方法,但我不知道如何在 XPath 表达式可能返回的 XElement 集合上使用它。

【问题讨论】:

    标签: c# xml xpath


    【解决方案1】:

    LINQ to 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
    

    【讨论】:

    • 谢谢,这很有用。但是,我必须使用 XPath 表达式,并且 XML 的结构可能会改变,因此我无法在代码中引用任何元素属性。无论如何,这帮助我找到了解决方案,因此非常感谢!
    【解决方案2】:

    这很简单,但我需要@Fabio 提醒我,foreach 是必要的:

    foreach (var element in foodXml.XPathSelectElements(xpathExpression))
    {
        element.AddAfterSelf(new XElement($"Review", "enjoyed"));
    }
    

    foodXml 现在在匹配元素之后有额外的享受元素

    【讨论】:

      【解决方案3】:

      还有这个 XPath 表达式:

      //Food[@course='dessert' and text() = 'Ice cream']
      

      这会找到每顿包含冰淇淋甜点的餐点。我想要 在每个匹配元素之后添加一个新元素,如下所示:

      那句话是错误的。你需要:

      /Meals/Meal[Food[@course = 'dessert'] = 'Ice cream']
      

      【讨论】:

      • 我已经编辑了这个问题,以明确 XPath 发现“每道冰淇淋甜点”而不是“每餐都有冰淇淋甜点”。 XPath 在问题中是正确的。没问题,我的问题是如何在 C# 中添加元素。还是谢谢你
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      相关资源
      最近更新 更多