0

Using XLinq, you seem to have to know the exact name of an element's children to access specific child elements. I want to access/discover the immediate children of an element recursivly without such tight coupling.

if I have:

<root>
  <level1/>
  <level1/>
  <level1>
    <level2.1>
    <level2.2>
      <level2.2.1/>
    </level2.2>
  </level1>
  <level1/>
</root>

In looking for "root"'s children, root.Elements().Count() returns 7 - I want 4 (the "level1" nodes). If I ask root.Elements("level1"), I get 4. But I have to know the name of the child elements.

Question: How can I access the immediate children without knowing that element name? And this would be at any recursive spot in the XML tree?

thanks.

---newly add: code --q1 == 7, q2 == 8 and q3 == 4. BUT, if you iterate through the elements of q3, you access all 7 child nodes rather than the 4 I'd want. If this means having to just to an ElementAt(#), fine. But the object seems to have a conflict between what it "sees" as it's children.

XElement xel = new XElement(
    new XElement("root",
        new XElement("level1"),
        new XElement("level1"),
        new XElement("level1",
                new XElement("level2.1"),
                new XElement("level2.2",
                    new XElement("level2.2.1"))),

                    new XElement("level1")
                    ));

var q1 = from x in xel.Descendants()
        select x;
var q2 = from x in xel.DescendantsAndSelf()
        select x;
var q3 = from x in xel.Elements()
        select x;

foreach (XElement x in q3.Elements())
{
    string s = x.ToString();
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • I guess you didn't post the XML you are actually using: `` is there only 4 times. – svick May 29 '11 at 18:34
  • Your updated XML is not valid, `` isn't closed. – svick May 29 '11 at 18:39
  • The sequence `q3` really only has 4 elements. But when you use `ToString()` on an element with children, it prints the whole element, including children. You would get the same behavior if you used `ElementAt()`. – svick May 29 '11 at 19:29

1 Answers1

1

In the case of the XML you posted, there is no difference between root.Elements() and root.Elements("level1"): both return the same 3 <level1> elements.

In general, XElement.Elements() does exactly what you want: returns only the immediate children of an element.

svick
  • 236,525
  • 50
  • 385
  • 514
  • sorry. new to this forum and had to learn needed to add > and such. I do get two distinct values. In the xml I'm using, there are 4 child nodes and I get all 14 decendents. – Llewellyn Preece May 29 '11 at 18:38
  • @Llewellyn, then post the XML you're actually using, your code and what do you expect the results to be. Also, you don't need to use HTML entities here, just input your code, select it, and then click on the `{ }` button. That formats it as code. – svick May 29 '11 at 18:41
  • Unless I hear otherwise, I have my best understanding of the answer: it does seem that one needs to ask the Element().Count() question to know the number of immediate children. Then one can iterate through each via the ElementAt(#). Using this approach recursively, one can, without knowledge of the element's metatag name, "visualize" the xml tree. It does seem sensible to have XElement have a "GetChildren" method since it has the concept of Parent. But that's easily created (each and every time). – Llewellyn Preece May 29 '11 at 19:24
  • @Llewellyn, but `Elements()` is exactly the method you want. No need for `ElementAt()`. – svick May 29 '11 at 19:31