none
Is it possible to get just the parents and not all ancestors? (going bottom up) RRS feed

  • Question

  • Have mapped XML tree data to a node class (called "Clade") containing subclasses for 'Children' and 'Parent' nodes. The Children class works, but the 'Parents' one doesn't. Tried to use the .Ancestors method (see 2nd loop) but it returns all ancestors (not the node's direct parent). using .Parent also does't work like .Children. 

    Is there a way to 1) somehow get the true Parents of the Clade when I map classes OR 2) somehow query/get the parent nodes from a leaf list (mine is called leafNodes)?

    My code below – have inserted ("//PROBLEM" in case helpful.

    void Start()
        {
            // load XML file into memory
            XDocument xmlTree = XDocument.Load(Application.streamingAssetsPath + "/tree.xml");
    
            //gen class for nodes/species/clades from XDocument 
            IEnumerable<Clade> clades = from n in xmlTree.Descendants("clade")
                                        select new Clade()
                                        {
                                            Name = (string)n.Element("name"),
                                            Branch_length = (float)n.Element("age_mya"),
                                            Orig_branch_length = (float)n.Element("orig_branch_length"),
                                            Children = from f in n.Elements("clade")
                                                                  select new Child()
                                                       {
                                                           Name = (string)f.Attribute("name"),
                                                       },
                                            Parents = from z in n.Ancestors("clade") //PROBLEM HERE?
                                               
                                                       select new ParentNode()
                                                       {
                                                           Name = (string)z.Attribute("name"),
                                                       }};
            //get leafs 
            IEnumerable<Clade> leafNodes = from Clade n in clades
                                           where n.Children.Count() == 0
                                           select n;
            //PROBLEM HERE: How to get the parent(s) of leaf nodes into a collection (so i can give them coordinates)?
            IEnumerable<Clade> parentsofLeafNodes = from Clade z in leafNodes
                                                    select z.Parents;              
        }
    
        class Clade
        {
            public string Name { get; set; }
            public float Branch_length { get; set; }
            public float Age_mya { get; set; }
            public float Orig_branch_length { get; set; }
            public IEnumerable<Child> Children { get; set; }
            public IEnumerable<ParentNode> Parents { get; set; }
        }
        class Child
        {
            public string Name { get; set; }
        }
        class ParentNode
        {
            public string Name { get; set; }
        }

    Data is this 'tree.xml' file of deeply nested species (sample of some child nodes below):

                                                                <name>Hominids</name>
                                                                <branch_length>72.1099999999996</branch_length>
                                                                <tol>16299</tol>
                                                                <age_mya>19.73</age_mya>
                                                                <pw_index>1</pw_index>
                                                                <orig_branch_length>72.1099999999996</orig_branch_length>
                                                                <clade>
                                                                  <name>unnamed node</name>
                                                                  <branch_length>15.158333333333758</branch_length>
                                                                  <tol>16416</tol>
                                                                  <age_mya>4.572</age_mya>
                                                                  <pw_index>2</pw_index>
                                                                  <orig_branch_length>15.158333333333758</orig_branch_length>
                                                                  <clade>
                                                                    <name>Homo</name>
                                                                    <branch_length>2.0953472222222445</branch_length>
                                                                    <tol>16418</tol>
                                                                    <age_mya>2.476</age_mya>
                                                                    <pw_index>2</pw_index>
                                                                    <orig_branch_length>2.0953472222222445</orig_branch_length>
                                                                    <clade>
                                                                      <name>Homo erectus</name>
                                                                      <branch_length>1.4763194444426517</branch_length>
                                                                      <tol>9999992</tol>
                                                                      <age_mya>1.0</age_mya>
                                                                      <orig_branch_length>1.4763194444426517</orig_branch_length>
                                                                    </clade>
                                                                    <clade>
                                                                      <name>Modern human</name>

    Please let me know if you know how to solve this / get parents. 
    Thankyou

     
    Sunday, August 26, 2018 1:33 PM

All replies

  • Try this:

    class Clade
    {
    	public string Name { get; set; }
    	public float Branch_length { get; set; }
    	. . .
    	public Clade Parent { get; set; }
    	public IEnumerable<Clade> Children { get; set; }
    }
    
    . . .
    
    static Clade ProcessCladeElement( XElement e, Clade parent )
    {
    	Clade clade = new Clade();
    
    	clade.Name = e.Element( "name" ).Value;
    	clade.Branch_length = float.Parse( e.Element( "branch_length" ).Value );
    	clade.Parent = parent;
    
    	clade.Children = e.Elements( "clade" ).Select( c => ProcessCladeElement( c, clade ) ).ToList();
    
    	return clade;
    }
    
    . . .
    
    XDocument xmlTree = XDocument.Load( ... );
    
    Clade root_clade = ProcessCladeElement( xmlTree.Root.Element( "phylogeny" ).Element( "clade" ), null );
    
    

    Monday, August 27, 2018 6:57 AM
  • Thanks for your response!

    Ok so tried the code for the past 1.5 hrs. I can call children and parents (see below). But it doesn't seem to map all the nodes in the file? 

    In other words, it seems it's mapping the root node, but not iterating through all because, for eg I can call root_clade.Children but not root_clade.Children.Children.. For eg, how does one call all leaf nodes?

    Tried 'foreach (Clade n in root_clade)" but root_clade seems to be one class, rather than a collection of all. Any advice?

    void Start()
        {
            // load XML file into memory
            XDocument xmlTree = XDocument.Load(Application.streamingAssetsPath + "/tree.xml");
            //gen class for nodes/species/clades from XDocument 
            Clade root_clade = ProcessCladeElement(xmlTree.Root.Element("phylogeny").Element("clade"), null);
    
            Debug.Log("Root name: " + root_clade.Name); // should show Life on Earth
            Debug.Log("Root parent: " + root_clade.Parent); // should show nothing
            Debug.Log("Root children: " + root_clade.Children + "children count: " + root_clade.Children.Count()); // one child should be 'unnamed node'
    
            // access/query all caldes / nodes
            //foreach (Clade n in root_clade) // error says MapTree.Clade does not contain a public instance definition for 'GetEnumerator'
        }
    
        public class Clade
        {
            public string Name { get; set; }
            public float Branch_length { get; set; }
            public float Age_mya { get; set; }
            public float Orig_branch_length { get; set; }
            public Clade Parent { get; set; }
            public IEnumerable<Clade> Children { get; set; }
        }
      
        public static Clade ProcessCladeElement(XElement e, Clade parent)
        {
            Clade clade = new Clade();
    
            clade.Name = e.Element("name").Value;
            clade.Branch_length = float.Parse(e.Element("branch_length").Value);
            clade.Parent = parent;
    
            clade.Children = e.Elements("clade").Select(c => ProcessCladeElement(c, clade)).ToList();
    
            return clade;
        }

    //data returned from running:

    Root name: Life on Earth Root parent: Root children: System.Collections.Generic.List`1[MapTree+Clade]children count: 2


    • Edited by MaxXR Monday, August 27, 2018 9:03 AM
    Monday, August 27, 2018 9:02 AM
  • Hi MaxXR,

    Thank  you for posting here.

    >>Tried 'foreach (Clade n in root_clade)" but root_clade seems to be one class, rather than a collection of all. Any advice?

    For your question, if you want to get the all child nodes, you could try the code below.

    foreach(var nodesname in doc2.Root.Descendants("Nodes name"))
    {
      //Do something with the node
      foreach(var children in nodesname.Descendants())
      {
         //Do something with the child nodes of nodesname.
      }
    }

    Best Regards,

    Wendy



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Proposed as answer by Stanly Fan Thursday, August 30, 2018 6:39 AM
    Tuesday, August 28, 2018 5:47 AM
    Moderator