How can I find a specific xml node?
I have this problem to find a specific xml node. I posed this issue on stackoverflow and some good contributors have suggested xpath.
I am new to xml. please i need C # code to find parent, parent, parent (great parent) and then first child, lastchild, lastchild. the code has to iterate the tree and down again. Have a look at many xpath tutorials online.
I found that the path is usually specific to a certain node already existing. The program I want will not get any name named node because on each pass a new node will be added to the xml tree. Long and short is that I need to find the base node in its place away from the current node
i meant find the parent parent of the current type (great parent class) then find the first child then find lastchild lastchild
keepkind of currentnode.parentnode.parentnode.parentnode.firstchild.lastchild.lastchild;
using xpath c #
a source to share
Let's say you have a named XmlNode instance node
to start with. Then the following code will give you the last child of the last child of the first child of the great great parent of that node:
XmlNode wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
Please note that there are many things that can go wrong with this code. If any of the referenced nodes are null, you will get a NullReferenceException. Therefore, you need to do a null check at every level:
XmlNode wantedNode;
if (node.ParentNode != null && node.ParentNode.ParentNode != null /* and so on through the full path */)
{
wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
}
Let's look at this with a more specific example. Suppose we have the following Xml document:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<greatgrandparent>
<grandparent>
<parent id="1">
<child somevalue="3"></child>
</parent>
<parent id="2">
<child somevalue="4"></child>
<child somevalue="5"></child>
</parent>
</grandparent>
</greatgrandparent>
</root>
If I understand your question correctly, if we start from node <child somevalue="3"></child>
we want to go to <child somevalue="5"></child>
. This code example will do just that. However, as mentioned, it tends to throw exceptions if not all expected nodes are present.
Even though you said you wanted to use C # code and not XPath, in this case I feel like XPath is the way to go. There are several ways to solve this problem. For example, if the nodes have different tag names (as in my example document), you can do the following:
XmlNode wantedNode = node.SelectSingleNode("ancestor::greatgrandparent/grandparent[position()=1]/parent[position()=last()]/child[position()=last()]");
if (wantedNode != null)
{
// the path was found
}
This assumes, of course, that node
it is not null but a valid XmlNode instance.
The XPath expression breakdown:
- ancestor :: greatgrandparent -> this will find any node named "greatgrandparent" that is located anywhere up in the hierarchy (so any parent, great parent, etc.)
- / grandparent [position () = 1] -> first child node named "grandparent"
- / parent [position () = last ()] β last child node named "parent"
- / child [position () = last ()] β last child node named "child"
If you'd like to read some on how XPath axes work there is some information on w3schools.com .
a source to share
All the questions you ask are answered with the XmlNode class . It has properties called ParentNode
, FirstChild
and LastChild
, each of which returns the other XmlNode
.
To do the same in XPath, you can use an abbreviation ".."
to get the parent node, and "*[position()=1]"
or "*[position()=last()]"
to get the first and last children, for example:
XmlNode foundNode = node.SelectSingleNode("../../../*[position()=1]/*[position()=last()]/*[position()=last()]");
(Notes: ".." is an abbreviation for the parent :: * axis, and "*" is an abbreviation for the "child :: *" axis)
a source to share