首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >根据c# LINQ中的子节点XML获取特定父节点

根据c# LINQ中的子节点XML获取特定父节点
EN

Stack Overflow用户
提问于 2018-05-04 13:12:25
回答 3查看 1.2K关注 0票数 3

我有一个很长的XML,它的父节点是sdnEntry,每个父节点都有它的子sdnType,它定义了条目的类型。我正在尝试仅获取包含 sdnType to Individual**.**的节点

下面是我的xml的简短示例;

代码语言:javascript
复制
<sdnEntry>
    <uid>6905</uid>
    <lastName>abc</lastName>
    <sdnType>Entity</sdnType> // type is entity

    <akaList>
    <aka>
        <uid>4741</uid>
        <type>a.k.a.</type>
        <category>strong</category>
        <lastName>ABC</lastName>
        <firstName>ABCCCC</firstName>
    </aka>
    <aka>
        <uid>4742</uid>
        <type>a.k.a.</type>
        <category>weak</category>
        <lastName>ADCS</lastName>
    </aka>
    </akaList>

    <nationalityList>
        <nationality>
        <uid>5416</uid>
        <country>XYZ</country>
        <mainEntry>true</mainEntry>
        </nationality>
    </nationalityList>
</sdnEntry>

<sdnEntry>
    <uid>6905</uid>
    <lastName>abc</lastName>
    <sdnType>Individual</sdnType> // type is individual

    <akaList>
    <aka>
        <uid>4741</uid>
        <type>a.k.a.</type>
        <category>strong</category>
        <lastName>ABC</lastName>
        <firstName>ABCCCC</firstName>
    </aka>
    <aka>
        <uid>4742</uid>
        <type>a.k.a.</type>
        <category>weak</category>
        <lastName>ADCS</lastName>
    </aka>
    </akaList>

    <nationalityList>
        <nationality>
        <uid>5416</uid>
        <country>XYZ</country>
        <mainEntry>true</mainEntry>
        </nationality>
    </nationalityList>
</sdnEntry>

<sdnEntry>
    <uid>6905</uid>
    <lastName>abc</lastName>
    <sdnType>Individual</sdnType>

    <akaList>
    <aka>
        <uid>4741</uid>
        <type>a.k.a.</type>
        <category>strong</category>
        <lastName>ABC</lastName>
        <firstName>ABCCCC</firstName>
    </aka>
    <aka>
        <uid>4742</uid>
        <type>a.k.a.</type>
        <category>weak</category>
        <lastName>ADCS</lastName>
    </aka>
    </akaList>

    <nationalityList>
        <nationality>
        <uid>5416</uid>
        <country>XYZ</country>
        <mainEntry>true</mainEntry>
        </nationality>
    </nationalityList>
</sdnEntry>

<sdnEntry>
    <uid>6905</uid>
    <lastName>abc</lastName>
    <sdnType>Entity</sdnType>

    <akaList>
    <aka>
        <uid>4741</uid>
        <type>a.k.a.</type>
        <category>strong</category>
        <lastName>ABC</lastName>
        <firstName>ABCCCC</firstName>
    </aka>
    <aka>
        <uid>4742</uid>
        <type>a.k.a.</type>
        <category>weak</category>
        <lastName>ADCS</lastName>
    </aka>
    </akaList>

    <nationalityList>
        <nationality>
        <uid>5416</uid>
        <country>XYZ</country>
        <mainEntry>true</mainEntry>
        </nationality>
    </nationalityList>
</sdnEntry>

我的代码是这样的,但我得到了错误;

代码语言:javascript
复制
 var lXelements = XElement.Parse(xml);
 var lParentNode = "sdnEntry";
  if (lParentNode == "sdnEntry")
            {
 //lXelements = (XElement)lXelements.Descendants("sdnType").Where(x => x.Name.LocalName == "Individual");
                lXelements = (XElement)lXelements.Descendants("sdnType").Where(x => (string)x.Value == "Individual");
            }

我得到了转换错误,我不知道我的这段代码会给我我想要的结果或不。

错误:

附加信息:无法将类型为'WhereEnumerableIterator`1System.Xml.Linq.XElement‘的对象强制转换为类型“”System.Xml.Linq.XElement“”。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-08 18:40:09

错误是因为您正在尝试将Linq Where结果重新分配给XElement

除此之外,您基本上希望获得具有子<sdnType>Individual</sdnType>的所有<sdnEntry>节点

代码语言:javascript
复制
XElement elements = XElement.Parse(xml);
var parentNode = "sdnEntry";
var childNode = "sdnType";
var childNodeValue = "Individual";
List<XElement> entries = elements
    .Descendants(parentNode)
    .Where(parent => parent.Descendants(childNode)
        .Any(child => child.Value == childNodeValue)
    ).ToList();

entries应仅包含与所提供的子元素筛选器匹配的所需父元素。

上面的方法基于父节点搜索子节点。

以下方法首先查找子节点,然后在树中查找父节点

代码语言:javascript
复制
List<XElement> entries = elements
    .Descendants(childNode)
    .Where(child => child.Value == childNodeValue)
    .SelectMany(child => child.Ancestors(parentNode))
    .ToList();

这两种方法都基于以下XML生成相同的两个匹配元素结果

代码语言:javascript
复制
var xml = @"
<sdnList>
    <sdnEntry>
        <uid>6905</uid>
        <lastName>abc</lastName>
        <sdnType>Entity</sdnType>

        <akaList>
        <aka>
            <uid>4741</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>ABC</lastName>
            <firstName>ABCCCC</firstName>
        </aka>
        <aka>
            <uid>4742</uid>
            <type>a.k.a.</type>
            <category>weak</category>
            <lastName>ADCS</lastName>
        </aka>
        </akaList>

        <nationalityList>
            <nationality>
            <uid>5416</uid>
            <country>XYZ</country>
            <mainEntry>true</mainEntry>
            </nationality>
        </nationalityList>
    </sdnEntry>

    <sdnEntry>
        <uid>6905</uid>
        <lastName>abc</lastName>
        <sdnType>Individual</sdnType> 

        <akaList>
        <aka>
            <uid>4741</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>ABC</lastName>
            <firstName>ABCCCC</firstName>
        </aka>
        <aka>
            <uid>4742</uid>
            <type>a.k.a.</type>
            <category>weak</category>
            <lastName>ADCS</lastName>
        </aka>
        </akaList>

        <nationalityList>
            <nationality>
            <uid>5416</uid>
            <country>XYZ</country>
            <mainEntry>true</mainEntry>
            </nationality>
        </nationalityList>
    </sdnEntry>

    <sdnEntry>
        <uid>6905</uid>
        <lastName>abc</lastName>
        <sdnType>Individual</sdnType>

        <akaList>
        <aka>
            <uid>4741</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>ABC</lastName>
            <firstName>ABCCCC</firstName>
        </aka>
        <aka>
            <uid>4742</uid>
            <type>a.k.a.</type>
            <category>weak</category>
            <lastName>ADCS</lastName>
        </aka>
        </akaList>

        <nationalityList>
            <nationality>
            <uid>5416</uid>
            <country>XYZ</country>
            <mainEntry>true</mainEntry>
            </nationality>
        </nationalityList>
    </sdnEntry>

    <sdnEntry>
        <uid>6905</uid>
        <lastName>abc</lastName>
        <sdnType>Entity</sdnType>

        <akaList>
        <aka>
            <uid>4741</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>ABC</lastName>
            <firstName>ABCCCC</firstName>
        </aka>
        <aka>
            <uid>4742</uid>
            <type>a.k.a.</type>
            <category>weak</category>
            <lastName>ADCS</lastName>
        </aka>
        </akaList>

        <nationalityList>
            <nationality>
            <uid>5416</uid>
            <country>XYZ</country>
            <mainEntry>true</mainEntry>
            </nationality>
        </nationalityList>
    </sdnEntry>
</sdnList>
";
票数 5
EN

Stack Overflow用户

发布于 2018-05-09 12:16:49

您可以尝试执行以下操作,看看它是否对您有帮助:这不使用lambda表达式,但与上面的Nkosi代码执行相同的操作

代码语言:javascript
复制
 XElement xe = XElement.Parse(xml);
        IEnumerable<XElement> newlist = (from x in xe.Elements("sdnEntry")
                                         where x.Element("sdnType").Value == "Individual"
                                         select x);
       ///Then at this point newlist contains all xelement where the sdnType=Individual
票数 1
EN

Stack Overflow用户

发布于 2018-05-04 14:07:41

您正在尝试将IEnumerable<XElement>转换为XElement。去掉演员模型,它应该会起作用:

代码语言:javascript
复制
lXelements = lXelements.Descendants("sdnType")
          .Where(x => (string)x.Value == "Individual");

...

foreach(var element in lXelements)
{
   DoSomething(element);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50167560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档