After a glitch of two days, I”m back. Unfortunately, Sushi decided that she had to be the center of the world in these last days and when she thought she wasn”t, she decided to jump straight from the second floor without a parachute…after, stairs are only for humans:,,) Fortunately, se didn”t hurt herself and half an hour later she was playing again…Now that you know why it took me so long to write another post, it”s time to get started.
Now that we know how to create, load and parse XML documents, it”s time to keep going and we”ll talk about several methods that will let us navigate through the existing nodes on an XML document. Lets start by presenting the XML we”ll be using:
var xml = new XElement( “clients”,
new XElement( “name”, “Luis”),
new XElement( “country”, “Portugal”)
new XElement( “name”, “John”),
new XElement( “country”, “England”)
new XElement( “name”, “Paulo”),
new XElement( “country”, “Portugal”)
Now, you can get the first child element of the clients element by calling the Element method:
var firstChild = xml.Element( “client” );
The Element method expects a XName and tries to find the first child element whose name matches the name you”ve passed in (do notice that the search is performed in document order). You could get all the client elements by calling the Elements method:
var children = xml.Elements();
There”s also an overload which receives a XName. As you”d expect, that overload will return all the elements whose name match the passed XName. Another thing you might need is to get all the descendants of a node. For instance, let”s suppose you want to get the names of all your customers. This is easily achieved by writing something like this:
var clientsNames = xml.Descendants(“name”);
There”s also an overload which doesn”t receive an XName. In that case, you”ll simply get all the descendant elements of the node over which you call that method. There is still another method which you might use to get all the descendant nodes: it”s called…yep, you”ve guessed it: DescendantNodes. The main difference when compared with the previous method is that you”ll get all the nodes and not only descendant elements. In practice, this means that if you run the method over the xml variable:
var descendants = xml.DescendantNodes();
besides getting all the element nodes, you”ll also get the text nodes that exist on the previous document. It”s important to keep in mind that LINQ to XML doesn”t consider attributes to be nodes. that”s why you won”t see any in the list returned by the previous method.
There”s also an overload that includes the node over which the method is executed in the candidate nodes to be returned. Those methods end with XXXAndSelf. So, for instance, if you want to get all the descendants + the current element, you could write the following code:
var clientsNames = xml.DescendantNodesAndSelf();
You can also go the other way, that is, you can get the ancestor of an existing element by calling one of the existing Ancestors(AndSelf) methods. So, if firstClient is a variable that points to the first client, you can get its parent by running the following code:
var firstClient = xml.Element(“client”);
var ancestor = firstClient.Ancestors().First();
Technically, First is not part of the LINQ To XML API, but since it”s introduced by LINQ To Objects, nothing prevents us from using it here since Ancestors returns a IEnumerable<T> collection.
You can also go sideways, by using the ElementsAfterSelf and the ElementsBeforeSelf method. Both methods have overloads that receive a XName and return only the elements whose name match that XName. Say that you”re on the second client. You can get the previous element by calling ElementsBeforeSelf. You can also see if an existing XNode is before or after the current node by calling the IsBefore or IsAfter method.
If you”re really into XPath, then you”ll be happy to know that there”s support for it, but I”ll leave it for a future post because I”m really out of time now. Keep tuned…