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

如何用LINQ查询XML父元素属性并匹配文件扩展名

XML与LINQ查询问题

一、需求:根据文件扩展名提取TargetId

现有如下XML结构:

<?xml version="1.0" encoding="UTF-8"?>
<Targets>
    <FileType TargetId="image">
        <FileExtension>jpg</FileExtension>
        <FileExtension>jpeg</FileExtension>
        <FileExtension>tif</FileExtension>
        <FileExtension>tiff</FileExtension>
        <FileExtension>gif</FileExtension>
        <FileExtension>png</FileExtension>
    </FileType>
</Targets>

需要根据指定的文件扩展名(如jpeg),查找并提取对应的TargetId。首次使用包含重复FileExtension元素的结构,始终无法匹配到目标。

二、过往测试中的属性访问异常

此前使用如下XML结构的测试代码可正常查询元素:

<body>
  <Customers>
    <Client TestAttr="testing-123">
        <Firstname>someguy</Firstname>
        <LastName>some other last name again</LastName>
        <PhoneNumber>12345634543</PhoneNumber>
        <City>some other town</City>
        <State>some other state</State>
    </Client>
  </Customers>
</body>

查询代码:

IEnumerable<XElement> someClients =
   from el in doc.Elements("Customers").Elements("Client")
   where (string)el.Element("PhoneNumber") == phoneNumberToFind
   select el;

能正常找到目标元素,也可获取同一Client下的其他元素:

Console.WriteLine("Found client named '{0}'", (string)el.Element("LastName").Value );

但访问元素属性时,所有尝试均触发NullReferenceException:

An unhandled exception of type 'System.NullReferenceException' occurred in ......dll: 'Object reference not set to an instance of an object.'

尝试的代码包括:

string fTestAttr1 = (string)el.Element("Client").Value;
string fTestAttr2 = (string)el.Element("Client").Attribute("TestAttr");
string fTestAttr3 = (string)el.Element("Client").Attribute("TestAttr").Value; 
string fTestAttr4 = (string)el.Element("Client").FirstAttribute.Value;   
string fTestAttr4 = (string)el.Element("Client").FirstAttribute.Value);

调试中可见el是XElement类型,但不清楚如何正确访问属性,也不明白为何会出现空引用异常。


解决方案

1. 解决属性访问的空引用问题

你之前的代码错误在于:el本身就是Client元素,不需要再调用el.Element("Client")——这会返回null,因为Client元素内部没有子元素叫Client,直接访问el的属性即可:

正确代码示例:

// 直接从el(即Client元素)获取属性
string testAttr = (string)el.Attribute("TestAttr");
// 或者用空条件运算符避免空引用,属性不存在时返回空字符串
string testAttrValue = el.Attribute("TestAttr")?.Value ?? string.Empty;

解释:

  • el是查询到的Client元素实例,Attribute("TestAttr")方法会直接返回该元素的TestAttr属性。
  • 使用(string)el.Attribute("TestAttr")更安全:如果属性不存在,会返回null而非抛出异常。
  • 若使用.Value,必须先判断属性是否为null,可通过?.和??组合避免空引用。

2. 根据文件扩展名查找TargetId的LINQ查询

针对目标XML结构,需要遍历FileType下的所有FileExtension子元素,匹配指定扩展名后,获取父元素FileType的TargetId属性。

示例代码(方法语法):

// 假设doc是加载好的XDocument对象
string extensionToFind = "jpeg";

string targetId = doc.Descendants("FileExtension")
    .Where(fe => (string)fe == extensionToFind)
    .Select(fe => (string)fe.Parent.Attribute("TargetId"))
    .FirstOrDefault();

// 输出结果
if (!string.IsNullOrEmpty(targetId))
{
    Console.WriteLine($"匹配到的TargetId: {targetId}");
}
else
{
    Console.WriteLine("未找到匹配的扩展名");
}

或者用查询语法:

string targetId = (from fe in doc.Descendants("FileExtension")
                   where (string)fe == extensionToFind
                   select (string)fe.Parent.Attribute("TargetId"))
                  .FirstOrDefault();

解释:

  • Descendants("FileExtension")会遍历XML中所有FileExtension元素,无需关心层级。
  • 匹配到目标扩展名后,通过fe.Parent获取父元素FileType,再提取TargetId属性。
  • FirstOrDefault()返回第一个匹配结果,无匹配时返回null,避免无结果时抛出异常。
  • 若XML中有多个FileType元素,需获取所有匹配结果,可将FirstOrDefault()替换为ToList()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 21:05:00