locked
XML/C# Select siblings simple question RRS feed

  • Question

  • Hi,

    I have an XML doc like

    <home>
      <window id=1></window>
       <room></room>
       <window id=2></window>
       <garden></garden>
    </home>

    My current node is window. I would like to retrieve the next sibling with the name "window".

    I tried

    node.NextSibling["window"];

    but this does not return any value. Do you have any other suggestions to retrieve the next sibling with a particular name?

    Thanks in advance!!

    Dennis
    Wednesday, March 11, 2009 11:23 AM

Answers

  • Yes and that is what this is code will do:

    XmlDocument doc = new XmlDocument();

    doc.Load("xmlfile.xml");

    // Select all page nodes at level book/

    XmlNodeList
    nodes = doc.SelectNodes("/book/page");

    //Iterate each node to do further processing
    foreach
    (XmlNode node in nodes)

    {

        // Check Nodes Here.....   
    }

    Best Regards,
    Rizwan


    Microsoft MVP - Visual Developer, C#
    Wednesday, March 11, 2009 1:43 PM
  • This snippet is incomplete.

    private bool checkSib(XmlNode node){  
     
     
       node = node.NextSibling;  
     
       if (node == nullreturn false;  
     
       while (node != null)   
     
       {  
     
           if (node.Name == "window"return true;  
     
           node = node.NextSibling;  
     
       }  
     
        return false;   
     
    }  
     

    It appears to something that is called by a method that DOES loop through the nodes in the file.  You should be using a switch statment somewhere to switch one XmlNodeType, anyway.

    /  
    //   
    // http://support.microsoft.com/default.aspx/kb/307548  read xml  
    // http://support.microsoft.com/kb/311566/   read xml  
    // http://support.microsoft.com/kb/309183/EN-US/  write ado.net to xml  
    // http://support.microsoft.com/kb/308343  xpathnavigator 


    Rudedog
    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 11, 2009 4:12 PM
    Moderator

All replies

  • Hi

    try this
    node.parentNode.childNodes.item(1) 
    should return room (zero indexed)

    HTH Ivo Stoykov
    • Proposed as answer by ivostoykov Wednesday, March 11, 2009 11:36 AM
    • Unproposed as answer by Dennis Klop Wednesday, March 11, 2009 12:21 PM
    Wednesday, March 11, 2009 11:36 AM
  • Thanks for you answer but this does return the desired element! Because you do not know at which next position the window element will be present.

    So, what I am looking for is something with a XPath expression for example. The code below works properly but this is not very efficient! There should be a more efficient way right?


    private bool checkSib(XmlNode node){

       node = node.NextSibling;

       if (node == null) return false;

       while (node != null)

       {

           if (node.Name == "window"return true;

           node = node.NextSibling;

       }

        return false;

    }

    Wednesday, March 11, 2009 12:26 PM
  • Try this link

    Find sibling node

    Thanks, A.m.a.L
    Wednesday, March 11, 2009 12:31 PM
  • That contains information about nodes and siblings, not an answer to retrieve the next sibling with a particular name!
    Wednesday, March 11, 2009 12:38 PM
  • Did you try getting XmlNodeList for all Window Elements by using SelectNodes function then Iterating through each XmlNode in nodelist?

    Best Regards,
    Rizwan
    Microsoft MVP - Visual Developer, C#
    Wednesday, March 11, 2009 1:20 PM
  • klop500 said:

    Thanks for you answer but this does return the desired element! Because you do not know at which next position the window element will be present.

    So, what I am looking for is something with a XPath expression for example. The code below works properly but this is not very efficient! There should be a more efficient way right?


    private bool checkSib(XmlNode node){

       node = node.NextSibling;

       if (node == null) return false;

       while (node != null)

       {

           if (node.Name == "window"return true;

           node = node.NextSibling;

       }

        return false;

    }

    do this to get window node

    node.parentNode.selectSingleNode("./window") 

    HTH Ivo Stoykov
    • Proposed as answer by ivostoykov Wednesday, March 11, 2009 1:34 PM
    • Unproposed as answer by Dennis Klop Wednesday, March 11, 2009 1:45 PM
    Wednesday, March 11, 2009 1:34 PM
  • Hi Rizwan, thanks for your reply!

    Well the point is that I would like the next node on the same level as my current node, so not the nodes that already have been processed.

    if I have

    <book> 
        <page val=1></page>
        <page val=2>
           <line id=0></line>
           <line id=1></line>
           <line id=2></line>
        </page>
        <missingpage></missingpage>
        <page val=4></page>
        <page val=5></page>

    </book>

    and my current node is 'page' with val=2, then I would like to return the next node 'page'. (which is 'page' with val=4 and not missingpage or a collection of all siblings which I have allready processed (for example a collection with 'page' val=1).

    Wednesday, March 11, 2009 1:38 PM
  • ivostoykov said:

    klop500 said:

    Thanks for you answer but this does return the desired element! Because you do not know at which next position the window element will be present.

    So, what I am looking for is something with a XPath expression for example. The code below works properly but this is not very efficient! There should be a more efficient way right?


    private bool checkSib(XmlNode node){

       node = node.NextSibling;

       if (node == null) return false;

       while (node != null)

       {

           if (node.Name == "window"return true;

           node = node.NextSibling;

       }

        return false;

    }

    do this to get window node

    node.parentNode.selectSingleNode("./window") 

    HTH Ivo Stoykov



    Hi ivostoykov, this also returns nodes which have already been processed. I only need the next siblings with a particular criteria! (=name)
    Wednesday, March 11, 2009 1:40 PM
  • Yes and that is what this is code will do:

    XmlDocument doc = new XmlDocument();

    doc.Load("xmlfile.xml");

    // Select all page nodes at level book/

    XmlNodeList
    nodes = doc.SelectNodes("/book/page");

    //Iterate each node to do further processing
    foreach
    (XmlNode node in nodes)

    {

        // Check Nodes Here.....   
    }

    Best Regards,
    Rizwan


    Microsoft MVP - Visual Developer, C#
    Wednesday, March 11, 2009 1:43 PM
  • True, but I do not loop through the nodes. I get a random node as input. The method is applied in a resursive function so it is difficult to know which node is the current node from a list of nodes in a for-statement.

    Isn't there a simple function that passes an argument to a sibling-functions?
    Wednesday, March 11, 2009 2:27 PM
  • klop500 said:

    True, but I do not loop through the nodes. I get a random node as input. The method is applied in a resursive function so it is difficult to know which node is the current node from a list of nodes in a for-statement.

    Isn't there a simple function that passes an argument to a sibling-functions?



    The above doesn't make any sense. 
    "...Get a random node as input.."  Random node name or random start point?
     "..but I do not loop through the nodes...."  The data is sequential in nature, so what do you propose?

    Besides, your nodes do not contain Values anyway, just Attributes.  That is why you originally got nothing back, because there was nothing to get. 

    Besides, you already stated that you have working code, but it "is not very efficient".  Just what exactly is your question anyway?

    Rudedog   =8^D
    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 11, 2009 3:56 PM
    Moderator
  • This snippet is incomplete.

    private bool checkSib(XmlNode node){  
     
     
       node = node.NextSibling;  
     
       if (node == nullreturn false;  
     
       while (node != null)   
     
       {  
     
           if (node.Name == "window"return true;  
     
           node = node.NextSibling;  
     
       }  
     
        return false;   
     
    }  
     

    It appears to something that is called by a method that DOES loop through the nodes in the file.  You should be using a switch statment somewhere to switch one XmlNodeType, anyway.

    /  
    //   
    // http://support.microsoft.com/default.aspx/kb/307548  read xml  
    // http://support.microsoft.com/kb/311566/   read xml  
    // http://support.microsoft.com/kb/309183/EN-US/  write ado.net to xml  
    // http://support.microsoft.com/kb/308343  xpathnavigator 


    Rudedog
    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 11, 2009 4:12 PM
    Moderator