Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all XML nodes with the same name without knowing their level?

Tags:

c#

xml

.net-3.0

I have a XML Example:

<Fruits>
    <Red_fruits>
        <Red_fruits></Red_fruits>
    </Red_fruits>
    <Yellow_fruits>
        <banana></banana>
    </Yellow_fruits>
    <Red_fruits>
        <Red_fruits></Red_fruits>
    </Red_fruits>
</Fruits>

I have 4 Red_fruits tags, 2 of them shares the same ParentNode (Fruits), I want to get those which have the same ParentNode.

But I just want those which have the same name (Red_fruits), which means Yellow_fruits tag isn't included.

This is the way I am doing right now using C# language:

XmlDocument doc = new XmlDocument();
string selectedTag = cmbX.text;

if (File.Exists(txtFile.text))
{
    try
    {
        //Load
        doc.Load(cmbFile.text);

        //Select Nodes
        XmlNodeList selectedNodeList = doc.SelectNodes(".//" + selectedTag);
    }
    Catch
    {
        MessageBox.show("Some error message here");
    } 
 }

This is returning me all red_fruits, not just the ones that belongs to Fruits.

I can't make XmlNodeList = doc.SelectNodes("/Fruits/Red_fruits") because I want to use this code to read random XML files, so I don't know the exact name that specific node will have, I just need to put all nodes with the same name and same level into a XmlNodeList using C# Language.

Is there a way of achieve this without using LINQ? How to do that?

like image 707
Rafael Vegaças Avatar asked Jul 17 '13 18:07

Rafael Vegaças


People also ask

How do I get XML nodes?

To find nodes in an XML file you can use XPath expressions. Method XmlNode. SelectNodes returns a list of nodes selected by the XPath string.

How do I count nodes in XML?

Count the XML elements (XPath)newInstance(). newXPath(); NodeList nodes = (NodeList) xpath. evaluate("//staff", doc, XPathConstants. NODESET); int count = nodes.

How many root nodes are there in XML?

While a properly formed XML file can only have a single root element, an XSD or DTD file can contain multiple roots.

What is the difference between XML node and element?

An Element is part of the formal definition of a well-formed XML document, whereas a node is defined as part of the Document Object Model for processing XML documents.


2 Answers

An understanding on the usage of Single Slash / and Double slash // can help here.

Let's see how / and // work in relation to the root node. When / is used at the beginning of a path:

/a

it will define an absolute path to node a relative to the root. As such, in this case, it will only find a nodes at the root of the XML tree.

When // is used at the beginning of a path:

//a

it will define a path to node a anywhere within the XML document. As such, in this case, it will find a nodes located at any depth within the XML tree.

These XPath expressions can also be used in the middle of an XPath value to define ancestor-descendant relationships. When / is used in the middle of a path:

/a/b

it will define a path to node b that is an immediate direct descendant (ie. a child) of node a.

When // used in the middle of a path:

/a//b

it will define a path to node b that is ANY descendant of node a.

Coming back to your question:

// using GetElementsByTagName() return all the Elements having name: Red_Fruits

XmlDocument doc = new XmlDocument();
XmlNodeList nodes= doc.GetElementsByTagName("Red_Fruits"); 

//Using SelectNodes() method

XmlNodelist nodes = doc.SelectNodes("//Fruits/Red_Fruits"); 

// This will select all elements that are children of the <Fruits> element.

In case <Fruits> is the root element use the Xpath: /Fruits/Red_Fruits. [ a single slash /]

like image 70
R.C Avatar answered Oct 20 '22 10:10

R.C


If you're simply trying to find the "next" or "previous" iteration of a single node, you can do the following and then compare it to the name

XmlNode current = doc.SelectSingleNode("Fruits").SelectSingleNode("Red_fruits");

XmlNode previous = current.NextSibling;
XmlNode next = current.NextSibling;

and you can iterate until you find the proper sibling

while(next.Name != current.Name)
{
    next = next.NextSibling;
}

or you can even get your list by invoking the 'Parent' property

XmlNodeList list = current.ParentNode.SelectNodes(current.Name);
like image 45
Sam I am says Reinstate Monica Avatar answered Oct 20 '22 10:10

Sam I am says Reinstate Monica