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

如何用LINQ从复杂XML中筛选含Individual的sdnEntry元素?

问题:获取XML中sdnType为Individual的sdnEntry元素

我有一个带命名空间的XML,需要提取所有<sdnType>值为Individual的<sdnEntry>元素,但尝试的代码无法正常运行。

我的XML内容

string list = @"<?xml version='1.0' standalone='yes'?>
                <sdnList xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://tempuri.org/sdnList.xsd'>
                <sdnEntry>
                    <uid>36</uid>
                    <lastName>AEROCARIBBEAN</lastName>
                    <sdnType>Entity</sdnType>
                    <programList>
                        <program>CUBA</program>
                    </programList>
                </sdnEntry>
                <sdnEntry>
                    <uid>173</uid>
                    <lastName>ANGLO-CARIBBEAN</lastName>
                    <sdnType>Entity</sdnType>
                    <programList>
                        <program>CUBA</program>
                    </programList>
                    </sdnEntry>
                <sdnEntry>
                    <uid>2681</uid>>
                    <title>NAME1 SURNNAME1</title>
                    <sdnType>Individual</sdnType>
                    <programList>
                        <program>SDGT</program>
                    </programList>                          
               </sdnEntry>
               <sdnEntry>
                    <uid>2682</uid>
                    <title>NAME2 SURNNAME2</title>
                    <sdnType>Individual</sdnType>
                    <programList>
                        <program>SDGT</program>
                    </programList>
                    <idList>
                        <id>
                        <uid>1002</uid>
                        <idType>Passport</idType>
                        <idNumber>304555</idNumber>
                        <idCountry>Egypt</idCountry>
                        </id>
                    </idList>
                </sdnEntry>
               </sdnList>";

尝试的错误代码

listXML.LoadXml(list);
XDocument sndList = XDocument.Parse(listXML.OuterXml);
var nls = XNamespace.Get("http://tempuri.org/sdnList.xsd");

//TEST 1
var individ = sndList.Elements(nls + "sdnEntry")
          .SelectMany(r => r.Descendants("sdnType").Where(e => (string)e.Element("sdnType").Value == "Individual"));

//TEST 2
IEnumerable<XElement> individuals =  from element in sndList.Root.Elements(nls + "sdnEntry")
                                     where (string)element.Element("sdnType") == "Individual"
                                     select element;

错误原因分析

  1. 命名空间未全局应用:XML根节点声明了默认命名空间xmlns='http://tempuri.org/sdnList.xsd',所有子元素(包括sdnType)都属于该命名空间。代码中获取sdnType时未加命名空间前缀,导致无法匹配元素,element.Element("sdnType")返回null。
  2. TEST1逻辑错误:SelectMany用法有误,试图在sdnType元素下查找sdnType子元素(e.Element("sdnType")),这不符合XML结构;且该逻辑返回的是sdnType元素,而非目标sdnEntry元素。
  3. 冗余XML转换:先加载到XmlDocument再转XDocument完全多余,直接用XDocument.Parse(list)即可完成加载。

正确解决方案

方法1:LINQ查询语法

XDocument sndList = XDocument.Parse(list);
XNamespace nls = XNamespace.Get("http://tempuri.org/sdnList.xsd");

IEnumerable<XElement> individuals = 
    from entry in sndList.Root.Elements(nls + "sdnEntry")
    let sdnType = entry.Element(nls + "sdnType")
    where sdnType != null && sdnType.Value == "Individual"
    select entry;

方法2:方法链语法

XDocument sndList = XDocument.Parse(list);
XNamespace nls = XNamespace.Get("http://tempuri.org/sdnList.xsd");

var individuals = sndList.Root
    .Elements(nls + "sdnEntry")
    .Where(entry => 
    {
        var sdnType = entry.Element(nls + "sdnType");
        return sdnType != null && sdnType.Value == "Individual";
    });

关键说明

  • 所有元素访问必须携带命名空间nls,包括sdnType。
  • 添加sdnType != null判断,可避免XML中缺失sdnType元素时触发空引用异常。
  • 直接通过XDocument.Parse(list)加载XML,简化流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:40:24