c# Xml到Linq删除一个项

本文关键字:一个 Xml Linq 删除 | 更新日期: 2023-09-27 18:11:03

我试图删除一个带有xml的项目到linq,但我不能让它工作:

<标题> Xml
<books>
    <book>
        <title>Harry Potter und der Stein der Waisen</title>
        <isbn>1</isbn>
        <author>J. K. Rowling</author>
       <price>30</price>
    </book>
</books>
<标题> DeleteItem h1> 试图导航到特定的元素,然后调用.Remove()
public void DeleteItem(Book toRemove)
{
  var xmlDoc = this.xmlFileStorage.LoadXmlDocument();
  xmlDoc
      .Descendants("books")
          .Elements("book")
              .Where(x => 
                  x.Elements("title").Single(y => y.Value == toRemove.Title)
                        && x.Elements("author").Single(y => y.Value == toRemove.Author)
                        && x.Elements("isbn").Single(y => y.Value == toRemove.Isbn)
                        && x.Elements("price").Where(y => y.Value == toRemove.Price.ToString()))
                    .Remove();
    this.xmlFileStorage.SaveXmlDocument(xmlDoc);
}

我认为.Single()不是正确的方法…我怎样才能从xml文档中得到确切的记录?

Thanks in advance

c# Xml到Linq删除一个项

我建议使用Element而不是Elements,并将XElement转换为string而不是使用Value。结合使用Title而不是title,应该没问题:

xmlDoc.Descendants("books")
      .Elements("book")
      .Where(x => (string) x.Element("title") == toRemove.Title
               && (string) x.Element("author") == toRemove.Author
               && (string) x.Element("isbn") == toRemove.Isbn
               && (string) x.Element("price") == toRemove.Price)
      .Remove();
当然,这将删除所有匹配的元素。如果你想确保只有一个匹配,你可以调用SingleOrDefault(),检查结果不是null,然后在XElement上调用Remove

另一个要考虑的选择是只是匹配ISBN -这实际上是书的标识符,不是吗?如果你的书碰巧有不同的价格,或者作者有不同的标点符号,你一定要这样做来防止被删除吗?

如果要删除第一个匹配节点,可以使用First。此外,您需要使用element而不是Elements。这应该对你有用:-

xmlDoc.Descendants("book").First(x => (string)x.Element("title") == toRemove.Title
                   && (string)x.Element("isbn") == toRemove.Author
                   && (string)x.Element("author") == toRemove.Isbn
                   && (string)x.Element("price") == toRemove.Price
                   ).Remove();
xmlDoc.Save(xmlPath);

您应该使用SelectSingleNode()

xmlDoc.SelectSingleNode("//parentnode//childnode");

以这种方式,您将访问所需的节点,使用linq,您将能够删除它。

xmlDoc.SelectSingleNode("//parentnode//childnode").Remove();

这段代码将移除您想要删除的值。

var model = xDoc.Descendants("book")
.Where(m => m.Element("element you want to match on to remove").Value == toRemove.ToString("value you want to match on"))
.FirstOrDefault();