You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何不限层级解析XML获取所有指定名称的PackageReference元素

问题原因

你的csproj文件根节点定义了默认命名空间http://schemas.microsoft.com/developer/msbuild/2003,所有子节点默认归属该命名空间。直接调用Descendants("PackageReference")时,方法会匹配无命名空间的节点,自然找不到结果。

解决方案

两种方案均可实现不限层级查找所有PackageReference节点:

方案1:指定命名空间查找(更严谨)

var text = System.IO.File.ReadAllText(@"C:\MyGit\TestXML3.csproj");
var root = XElement.Parse(text);
// 声明XML默认命名空间
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
// 递归查找所有带命名空间的PackageReference节点,不限层级
var packageReferences = root.Descendants(ns + "PackageReference");

foreach (var pkg in packageReferences)
{
    string packageName = pkg.Attribute("Include")?.Value;
    // 优先取Version属性,没有就取Version子元素的值
    string version = pkg.Attribute("Version")?.Value 
                    ?? pkg.Element(ns + "Version")?.Value;
    if (!string.IsNullOrEmpty(packageName) && !string.IsNullOrEmpty(version))
    {
        _packageList.Add(new Package()
        {
            App = app, 
            PackageName = packageName, 
            PackageVersion = version, 
            Project = projectName
        });
        // 直接输出可执行:Console.WriteLine($"{packageName};{version}");
    }
}

方案2:匹配本地名称(兼容性更强,不受命名空间变更影响)

如果不需要严格校验命名空间,可以直接匹配节点的本地名称,不用声明命名空间:

var text = System.IO.File.ReadAllText(@"C:\MyGit\TestXML3.csproj");
var root = XElement.Parse(text);
// 递归查找所有本地名称为PackageReference的节点,不限层级
var packageReferences = root.Descendants()
    .Where(x => x.Name.LocalName == "PackageReference");

foreach (var pkg in packageReferences)
{
    string packageName = pkg.Attribute("Include")?.Value;
    string version = pkg.Attribute("Version")?.Value 
                    ?? pkg.Elements().FirstOrDefault(e => e.Name.LocalName == "Version")?.Value;
    if (!string.IsNullOrEmpty(packageName) && !string.IsNullOrEmpty(version))
    {
        _packageList.Add(new Package()
        {
            App = app, 
            PackageName = packageName, 
            PackageVersion = version, 
            Project = projectName
        });
    }
}
注意点

你之前的代码中直接取packageReference.Value的逻辑存在风险:如果PackageReference下有除了Version之外的其他子元素,会把所有子元素的文本拼接返回。修正后优先取Version属性,不存在时显式查找Version子元素取值,逻辑更严谨。

内容的提问来源于stack exchange,提问作者user3132499

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:36:08