如何在 C# 中删除 csproj 文件中的节点?

How to delete a node in csproj file in c#?

我要删除节点<Reference Include="System.Data" />

以编程方式从 csproj 文件中获取。 我的 csproj 文件文件结构是这样的:

<ItemGroup>
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data.OracleClient" />
    <Reference Include="System.Messaging" />
    <Reference Include="System.Web.DynamicData" />
    <Reference Include="System.Web.Entity" />
    <Reference Include="System.Web.ApplicationServices" />
    <Reference Include="System.ComponentModel.DataAnnotations" />
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Web.Extensions" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Web" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Web.Services" />
    <Reference Include="System.EnterpriseServices" />
  </ItemGroup>

我正在尝试使用此代码,但它不起作用:

XmlDocument doc = new XmlDocument();
doc.Load(fullFilePath);
XmlNode node = doc.SelectSingleNode(@"/Project/ItemGroup/Reference[@Include='System.Data']");

node.ParentNode.RemoveChild(node);

doc.Save(fullFilePath);

当你 SelectNodes 或 SingleSelectNodes returns 什么都没有时,这意味着你的查询是错误的。在这种情况下,.csproj 中的元素属于命名空间(此处声明为 "default" 命名空间 - w/o 前缀)

<Project ... xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
</Project>

所以你的代码必须改成这样:

XmlDocument doc = new XmlDocument();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
nsmgr.AddNamespace("p", "http://schemas.microsoft.com/developer/msbuild/2003");
doc.Load(fullFilePath);
XmlNode node = doc.SelectSingleNode(@"/p:Project/p:ItemGroup/p:Reference[@Include='System.Data']", nsmgr);

node.ParentNode.RemoveChild(node);

doc.Save(fullFilePath);

注意前缀 "p" 可以是任何东西,它只允许您在 XPATH 表达式中指定相应的命名空间,但您需要它,即使在原始文档中它被声明为默认命名空间。

使用 XML Linq

很容易
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<Root>" +
                    "<ItemGroup>" +
                        "<Reference Include=\"Microsoft.CSharp\" />" +
                        "<Reference Include=\"System.Data.OracleClient\" />" +
                        "<Reference Include=\"System.Messaging\" />" +
                        "<Reference Include=\"System.Web.DynamicData\" />" +
                        "<Reference Include=\"System.Web.Entity\" />" +
                        "<Reference Include=\"System.Web.ApplicationServices\" />" +
                        "<Reference Include=\"System.ComponentModel.DataAnnotations\" />" +
                        "<Reference Include=\"System\" />" +
                        "<Reference Include=\"System.Data\" />" +
                        "<Reference Include=\"System.Core\" />" +
                        "<Reference Include=\"System.Data.DataSetExtensions\" />" +
                        "<Reference Include=\"System.Web.Extensions\" />" +
                        "<Reference Include=\"System.Xml.Linq\" />" +
                        "<Reference Include=\"System.Drawing\" />" +
                        "<Reference Include=\"System.Web\" />" +
                        "<Reference Include=\"System.Xml\" />" +
                        "<Reference Include=\"System.Configuration\" />" +
                        "<Reference Include=\"System.Web.Services\" />" +
                        "<Reference Include=\"System.EnterpriseServices\" />" +
                      "</ItemGroup>" +
                  "</Root>";

            XDocument doc = XDocument.Parse(input);
            List<XElement> itemGroup = doc.Descendants("ItemGroup").ToList();

            itemGroup.Elements("Reference").Where(x => x.Attribute("Include").Value == "System.Data").Remove();
        }
    }
}
​