繁体   English   中英

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

[英]getting specific parent nodes depending on child nodes XML in c# LINQ

我有一个长XML ,其父节点为sdnEntry ,每个父节点都有其子sdnType ,它定义了条目的类型。 我试图只将sdnTypeIndividual节点。

我的xml的简短示例在这里;

<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>

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

 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`1 [System.Xml.Linq.XElement]”的对象强制转换为“ System.Xml.Linq.XElement”。

该错误是因为您试图将Linq Where结果重新分配给XElement

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

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应仅包含与提供的子元素过滤器匹配的所需父元素。

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

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

List<XElement> entries = elements
    .Descendants(childNode)
    .Where(child => child.Value == childNodeValue)
    .SelectMany(child => child.Ancestors(parentNode))
    .ToList();

两种方法基于以下XML产生了相同的2个匹配元素结果

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>
";

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

 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

您正在尝试将IEnumerable<XElement> XElementXElement 删除演员表,它应该可以工作:

lXelements = lXelements.Descendants("sdnType")
          .Where(x => (string)x.Value == "Individual");

...

foreach(var element in lXelements)
{
   DoSomething(element);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM