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