使用 XDocument 按属性查找元素

Posted

技术标签:

【中文标题】使用 XDocument 按属性查找元素【英文标题】:Find Elements by Attribute using XDocument 【发布时间】:2010-04-20 20:05:13 【问题描述】:

此查询似乎有效,但我有 0 个结果。

IEnumerable<XElement> users =
            (from el in XMLDoc.Elements("Users")
             where (string)el.Attribute("GUID") == userGUID.ToString()
             select el);

我的 XML 如下:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Users>
  <User GUID="68327fe2-d6f0-403b-a7b6-51860fbf0b2f">
    <Key ID="F7000012ECEAD101">
      ...
    </Key>
  </User>

</Users>

你有什么线索可以阐明这一点吗?

【问题讨论】:

【参考方案1】:

嗯,Users 元素没有 GUID 属性。两个建议选项:

XDocument.Root.Elements("User") 使用Descendants("User") 查找所有用户元素。

我暂时坚持前者。这给了我们:

IEnumerable<XElement> users =
            (from el in XMLDoc.Root.Elements("User")
             where (string) el.Attribute("GUID") == userGUID.ToString()
             select el);

现在,我们仍然可以进一步整理。首先,让我们转换为Guid 而不是string

IEnumerable<XElement> users =
    (from el in XMLDoc.Root.Elements("User")
     where (Guid) el.Attribute("GUID") == userGUID
     select el);

但是,在这里使用查询表达式的理由并不多……您所应用的只是一个谓词。让我们直接使用Where 方法:

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid) el.Attribute("GUID") == userGUID);

当然,如何布局取决于您 :) 如果行较长,您可能可以将所有内容排列在较长的第一行之下:

IEnumerable<XElement> users = XMLDoc.Root
                                    . etc

现在,最后 - 如果 User 元素没有 GUID 属性怎么办?目前,此代码将引发异常。这可能正是您想要的——也可能不是。如果不是,您可以通过转换为 Nullable&lt;Guid&gt; aka Guid? 来使其忽略这些事情:

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid?) el.Attribute("GUID") == userGUID);

【讨论】:

谢谢,这也很有用,可惜我只能将一个标记为正确。【参考方案2】:

将第二行中的Users 更改为User。像这样:

    IEnumerable<XElement> users = (from el in XMLDoc.Root.Elements("User")
                                   where (string)el.Attribute("GUID") ==  userGUID.ToString()
                                   select el);

我假设 XMLDoc 是一个 XDocument,而不是根元素本身。

【讨论】:

谢谢,这部分是我需要的,我犯了一个愚蠢的错误。 正如 Jon 在下面指出的那样,强制转换为正确的类型是更好的选择。此外,如果您使用 "el.Attribute("GUID").Value" 您会自动获得一个字符串作为返回类型,并且不需要强制转换。 rootXMLDoc.root.Elements("User") 中应该是Root 我知道这是一篇较旧的帖子,但假设 userGUID 是 GUID,它不应该是 'where el.Attribute("GUID").Value == userGUID.ToString()' 吗? 如何使用 Sharepoint _api 提要实现相同的目标?我想从每个父元素中获取多个子元素?

以上是关于使用 XDocument 按属性查找元素的主要内容,如果未能解决你的问题,请参考以下文章

在 XDocument 中按名称查询任意深度的元素

使用属性过滤器读取 XDocument 的后代元素

计算 XDocument 上的子节点

当我们有多个同名但属性不同的元素时,如何使用 Xdocument 从 xml 中删除一个元素

按属性查找元素

xpath按元素和属性查找节点,其中包含具有特定id的子元素