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?
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.
Count the XML elements (XPath)newInstance(). newXPath(); NodeList nodes = (NodeList) xpath. evaluate("//staff", doc, XPathConstants. NODESET); int count = nodes.
While a properly formed XML file can only have a single root element, an XSD or DTD file can contain multiple roots.
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.
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 /
]
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With