Page 3 of 3
The value of it all
XML is about a standard format for data and just occasionally we need to actually get at the data.
As already mentioned, if an XElement has a single XText child node then you can access this data as a string using the Value property. However, if it has multiple XText child objects, perhaps contained within other XElement child objects, then the Value property contains a concatenation of these strings.
This makes processing data contained within tags a matter of navigating down to the XElement object which corresponds to the last pair of tags that enclose the text in question. Again, as already mentioned, XAttributes are easier to deal with in this sense because they always correspond to a single name value pair. In this case the Value property always contains the data we are interested in.
For simplicity the following examples will deal with XAttributes but the same methods work with XElement objects.
You could just assign a new value to the Value property but it is usually easier to use the SetValue method because this performs automatic type conversions.
XAttribute Att1 =new XAttribute("Epoc",2000);
Att1.Value = "2008";
works and sets the attribute to a string “2008”.
Att1.Value = 2008;
generates a runtime error because you need an explicit conversion.
Att1.Value = 2008.ToString();
The good news is that:
works without the need for an explicit conversion, as does:
Going the other way is almost as easy but you do have to use an explicit cast and don’t need to use Value.
DateTime T = Att1.Value;
doesn’t work, neither does;
DateTime T = (DateTime) Att1.Value;
but, perhaps surprisingly:
DateTime T = (DateTime) Att1;
You can cast and XAttribute to any numeric, bool, DateTime, TimeSpan and Guid. You can also cast to nullable versions of each of these data types, which can make handing missing data easier.
Converting to real XML
There is more to XML than a node tree.
You can add many of the XML “decorations” by wrapping the root XElement node in an XDocument object. This can have only one XElement object as the root but also a single XDeclaration, single XDocumentType and any number of XProcessingInstruction and XComment objects.
As you can easily work out, each of these objects adds a corresponding “meta” tag to the XML that the XDocument represents. There are various, very reasonable, rules about when declarations are emitted, default declarations, and other bookkeeping concerns – all very obvious.
Namespaces are also fairly simple but deserve a simple example. All XNames are created by default with an empty namespace. There are lots of different ways of adding a namespace specifier but the most useful is via the XNamespace class.
For example, to add a namespace to a name you could use:
XNamespace ns = "http://www.i-programmer.info";
XName fullname = ns + "root";
Notice that an XName has LocalName, NameSpace, and NameSpaceName properties to allow you to work more creatively with XML names. Also remember that all strings that you use in XElement, XAttribute etc names are automatically converted to XName objects.
If you use a namespace then you have to explicitly include it when creating each element of the tree and you have to use it when searching for elements with specific names.
That's more or less all there is to working with XML. Next we look at how to manipulate it using Linq see: Linq and XML.
If you would like to be informed about new articles on I Programmer you can either follow us on Twitter, on Facebook , on Digg or you can subscribe to our weekly newsletter.