I'm new to Linq to Xml. I have a very simple xml file like this:
<Items>
<Item>
<Stuff>Strings</Stuff>
</Item>
<Item>
<Stuff>Strings</Stuff>
</Item>
</Items>
And I'm trying to query it like this:
XDocument doc = XDocument.Load(myStream)
from node in doc.Descendants(XName.Get("Item"))
select new { Stuff = node.Element(XName.Get("Stuff")).Value }
But doc.Descendents(XName.Get("Item")) returns null. Something is wrong with my understanding here.
From stackoverflow
-
Try using doc.Root.Decendants("Item")
-
There's an implicit conversion from System.String to XName, so the more usual form is
...doc.Descendants("Item")
and
...node.Element("Stuff").Value
Besides that, I suggest doc.Root.Descendants() as in the previous answer. The document is still at the "top" of the hierarchy when it's loaded. I was under the impression that Descendants() was recursive, but who knows, right?
BC : Thanks for the tip, thats much easier to read and write. -
Your code actually works:
static void Main(string[] args) { string xml = @" <Items> <Item> <Stuff>Strings</Stuff> </Item> <Item> <Stuff>Strings</Stuff> </Item> </Items>"; using (StringReader myStream = new StringReader(xml)) { XDocument doc = XDocument.Load(myStream); var query = from node in doc.Descendants(XName.Get("Item")) select new { Stuff = node.Element(XName.Get("Stuff")).Value }; foreach (var item in query) { Console.WriteLine("Stuff: {0}", item.Stuff); } }
It should be noted that if the elements are not qualified with namespaces, then you don't really need XName:
static void Main(string[] args) { string xml = @" <Items> <Item> <Stuff>Strings</Stuff> </Item> <Item> <Stuff>Strings</Stuff> </Item> </Items>"; using (StringReader myStream = new StringReader(xml)) { XDocument doc = XDocument.Load(myStream); var query = from node in doc.Descendants("Item") select new { Stuff = node.Element("Stuff").Value }; foreach (var item in query) { Console.WriteLine("Stuff: {0}", item.Stuff); } } }
BC : You're right. It does work. But when I break with the debugger and start examining the object model with the command window, it does not work. I never actually tried executing it without stepping through. Do you have any insight into this?BC : I broke on the line containing the linq query and executed "? doc.Descendants("Item")" in the command window.casperOne : @BC: If you put it in the watch window, you get null? Or it says that it throws an exception?BC : If I put doc.Descendants("Item") in the watch, the value before and after the query is "This expression causes side effects and will not be evaluated."BC : Maybe it can it only be evaluated once?casperOne : @BC: No, you should be able to evaluate it multiple times. You need to post a complete code example, and detail where you set the break, as well as what you are trying to observe.BC : I can force the evaluation multiple times in the watch using the little recycle icon. Thanks for your help.
0 comments:
Post a Comment