C# XDocument 如何使用 linq 过滤元素

Posted

技术标签:

【中文标题】C# XDocument 如何使用 linq 过滤元素【英文标题】:C# XDocument how to use linq to filter elements 【发布时间】:2021-07-22 16:43:03 【问题描述】:

我正在使用从内存流中读取 xml

XDocument doc = XDocument.Load(targetStream);

foreach (XElement element in doc.Root.Elements())

     Console.WriteLine(element);

我的元素之一如下所示。我不确定为什么将命名空间 xmlns 添加到每个元素。基本上我想过滤 SerialNo = 01 的所有“标题”元素

<Header xmlns="LR/2020-21">
  <CollectionDetails>
    <Collection>ILR</Collection>
    <Year>2021</Year>
    <FilePreparationDate>2020-05-08</FilePreparationDate>
  </CollectionDetails>
  <Source>
    <ProtectiveMarking>OFFICIAL-SENSITIVE-Personal</ProtectiveMarking>
    <UKPRN>99999999</UKPRN>
    <SoftwareSupplier>SupplierName</SoftwareSupplier>
    <SoftwarePackage>SystemName</SoftwarePackage>
    <Release>1</Release>
    <SerialNo>01</SerialNo>
    <DateTime>2020-05-08T09:14:05</DateTime>
    <!-- This and the next element only appear in files generated by FIS -->
    <ReferenceData>Version5.0, LARS 2018-08-01</ReferenceData>
    <ComponentSetVersion>1</ComponentSetVersion>
  </Source>
</Header>

即使是下面的代码也带来了空记录

        IEnumerable<XElement> list1 =
                            from el in doc.Descendants("Header")
                            where (string)el.Attribute("xmlns") == "LR/2020-21"

                            select el;

谁能帮帮我。

谢谢

【问题讨论】:

你能显示根元素吗?是否设置了命名空间? 【参考方案1】:

因此,如果您想过滤命名空间,您需要为元素名称提供正确的命名空间。像这样:

var ns = XNamespace.Get("LR/2020-21");

var headers = doc.Root
    .Elements(ns + "Header")
    .Where(e => (string)e.Element(ns + "Source").Element(ns + "SerialNo") == "01");

如果同一Header元素中存在多个SerialNo,则可以使用以下表达式。

var ns = XNamespace.Get("LR/2020-21")

var matchingHeaders = doc.Root
    .Elements(ns + "Header")
    .Where(header => header
        .Elements(ns + "Source")
        .Any(source => source
            .Elements(ns + "SerialNo")
            .Any(serialNo => (string)serialNo == "01")))

【讨论】:

为什么最后是.ToList() 谢谢,但如果同一个
中有多个 元素,则会出现另一个问题。你能帮我怎么做吗?
@speyck 根据使用情况,这可能不是必需的。当然,我会删除它。 @MukilDeepthi 那么在同一个源元素中是否有多个序列号元素,或者是否有多个源元素,每个源元素都有一个序列号元素? @TorbjörnHansson 实际问题是***.com/questions/67315250/…

以上是关于C# XDocument 如何使用 linq 过滤元素的主要内容,如果未能解决你的问题,请参考以下文章

当元素的名称中有冒号时,如何使用 LINQ 查询 XDocument?

如何在构建 XDocument 时执行 LINQ 查询?

C# linq to Xml(复习用)

如何在 C# 中使用 LINQ 过滤嵌套字典?

如何使用 Foreach 遍历集合以构建 XDocument?

使用 XDocument 和 Linq 读取 XML - 检查元素是不是为 NULL?