Deep C# - XML in C#
Written by Mike James   
Thursday, 11 February 2021
Article Index
Deep C# - XML in C#
XML to XElement
Value

.NET has some really easy-to-use facilities for creating and editing XML. Many of these facilities were introduced to make Linq to XML work better, but you can make use of them in more general situations.

This is  a Chapter of our ebook on C# - a work in progress.

Deep C#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing ***NEW!
  3. Value & Reference
  4. Structs & Classes
  5. Inheritance
  6. Interfaces & Multiple Inheritance
  7. Controlling Inheritance

    II Casting & Generics
  8. Casting - The Escape From Strong Typing
  9. Generics
  10. Advanced Generics
  11. Anonymous & Dynamic

    Typing
    III Functions
  12. Delegates
  13. Multicast Delegates
  14. Anonymous Methods, Lambdas & Closures

    IV Async
  15. Threading, Tasks & Locking
  16. The Invoke Pattern
  17. Async Await
  18. The Parallel For

    V Data - LINQ, XML & Regular Expressions
  19. The LINQ Principle
  20. XML
  21. LINQ To XML
  22. Regular Expressions

    VI Unsafe & Interop
  23. Interop
  24. COM
  25. Custom Attributes
  26. Bit Manipulation
  27. Advanced Structs
  28. Pointers 

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>


There always was good XML support in .NET but Linq adds a set of classes that makes it easier to work with XML, particularly if you’re not an XML specialist.

There are a number of standard protocols and ways of working with XML – Xpath, SAX, DOM and so on.

All of them are good but they all focus on some specific particular aspect of XML and a particular way of getting the job done. Linq’s version of XML goes “back to basics”.

It is important to realise that much of what we are about to investigate can be used without the need to make use of Linq - it all just happens to be a very easy way to work with XML in general.

Even if you aren’t interested in working with XML looking at how Linq handles a more complicated data structure, a tree in this case, is instructive and has a lot to teach you about the way Linq is designed, how it works and how you might extend it to other data structures.

In this article we look at how to construct the tree structure that XML is all about and in a future article we look at how to use such structures with Linq.

Xelement

The core of XML is the tag as in

  • an opening tag, e.g. <Record>
  • a closing tag, e.g. </Record>

The rules for XML are simple – tags occur, almost always, in matched pairs and you can nest tags as if they were brackets.

The only exception to the matched pairs rule is a tag that is its own closing tag – as in <Record/> which opens and closes the tag in one go.

It’s not difficult to see that you can use tags to build a general tree structure and all you need to represent it in a program is a class that has a collection of itself as a property.

This is exactly how the xNode class, and the more useful xElement descended from it via xContainer, operate.

The important point is that xElement has a Nodes collection which can be used to store an element’s child elements.

A simple example will make this clear.

First we need a root node:

XElement root = new XElement("Record");

The string “Record” is automatically converted to an XName object and this is used to set the Name property of the new XElement.

An XName is used instead of a simple string because XML names have some additional behaviour because of namespaces – more later.

Now have a root for our tree let’s create a leaf node

XElement child1 = new XElement("Name");

and hang it off the tree….

root.Add(child1);

If you place a textbox on a form you can see the XML that the tree represents using:

textBox1.Text = root.ToString();

What you will see is:

<Record>
<Name />
</Record>

You can carry on in the same way to build up a tree of any complexity you like.

For example:

XElement root=new XElement("Record");
XElement child1=new XElement("Name");
root.Add(child1);
XElement child2=new XElement("First");
XElement child3=new XElement("Second");
child1.Add(child2);
child1.Add(child3);
XElement child4=new XElement("Address");
root.Add(child4);

creates the following XML:

<Record>
 <Name>
  <First />
  <Second />
 </Name>
 <Address />
</Record>

The idea of nesting XElements within XElements is fairly obvious but there are neater ways of achieving the same result.

For example, you can combine the two Add methods into a single call:

child1.Add(child2,child3);

The reason this works is due to an overload of Add not mentioned in the documentation:

public void Add(params object[] content);

You can, of course construct a list of child objects to insert into multiple XElements if you want to.

csharp

Another style of XML tree construction is based on the use of the XElement constructor.

One overloaded version allows you to specify the XElements content. So to create an XElement with two children you would use:

XElement root = new XElement("Record",
                   new XElement("Name"),
                    new XElement("Address"));

You can continue this nested construction to any level you need to.

For example, the following creates the same XML tree we had earlier:

XElement root = new XElement("Record",
    new XElement("Name",
     new XElement("First"),
     new XElement("Second")),
    new XElement("Address"));

This is generally referred to as “functional construction” and if you format it correctly then it looks like the tree it is constructing and it has the advantage that you can pass it directly to any method that cares to make use of it.

Of course in this style of construction you don’t get variables to keep track of each node but in most cases you don’t need them.



Last Updated ( Thursday, 11 February 2021 )