开发者

Finding a specific XML element based on an ID using Linq

开发者 https://www.devze.com 2022-12-09 12:50 出处:网络
I want to find a section of xml based on a criteria so I’m using linq to XML. Unfortunately the result is always null so I guess I’ve done something wrong. Shown below is an example of the XML I’m

I want to find a section of xml based on a criteria so I’m using linq to XML. Unfortunately the result is always null so I guess I’ve done something wrong. Shown below is an example of the XML I’m parsing.

<Stuff>
 <ItemsA />
 <ItemsB />
 <ItemsC>
  <Item xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Stuff">
   <Id>4bd7b5ac-cb29-4d34-97be-deaebe4a5186</Id>
   <Children>
    <Item>
      <Id>22e3ef6b-4321-40c3-9237-196ba527e9ad </Id>
      <Name>S开发者_如何转开发omeName</Name>
    </Item>
   </Children>
  <Description>SomeText</Description>
  <Name>NewName</Name>
</Item>    

I’m looking at the “ItemsC” section where there may be multiple “Item” blocks of XML (only one shown in this example). I want to retrieve the element based on its “Id”, the one with an Id of “4bd7b5ac-cb29-4d34-97be-deaebe4a5186” in the above example.

The code I have used is shown below:

XElement data = XElement.Parse(GetFile());

  var pbp = (from b in data.Descendants("Item")
             where b.Element("Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"
             select b.Element("Id").Parent).FirstOrDefault();

pbp always returns as null. Can anyone help me to produce the correct linq expression.


Yup - you're just missing the namespace:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186";
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff";
var pbp = (from b in data.Descendants(ns + "Item")
           where b.Element(ns + "Id").Value == desiredId
           select b).FirstOrDefault();

Note that I simplified the b.Element("Id").Parent to just b - if you're just going down the tree and then up again, you might as well stay where you are :)

This suggests a further simplification to use dot notation:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186";
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff";
var pbp = data.Descendants(ns + "Item")
              .Where(b => b.Element(ns + "Id").Value == desiredId)
              .FirstOrDefault();

If there's a chance that the element won't have an "Id" element, then you can cast to a string instead:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186";
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff";
var pbp = data.Descendants(ns + "Item")
              .Where(b => (string) b.Element(ns + "Id") == desiredId)
              .FirstOrDefault();

That avoids a possible NullReferenceException.


You just need to add the namespace to the query, i.e.

XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff";

var pbp =
   (from b in data.Descendants(ns + "Item")
   where b.Element(ns + "Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"
   select b.Element(ns + "Id").Parent).FirstOrDefault();
0

精彩评论

暂无评论...
验证码 换一张
取 消