How to transform XML with LINQ to XML in C#

You can find from the articles: How to use XSL to transform XML content, How to use XslCompiledTransform class to transform XML file in C#, and How to use Xml control to transform XML file to HTML output different ways to change the representation of XML. Although XSL will still continue to be used in a wide range of scenarios, LINQ to XML offers a compelling alternative.

To perform a transformation with LINQ to XML, you need to use a LINQ expression that uses a projection described in the article: How to use LINQ expression to do projection in C#. The trick is that the projection must return an XElement rather than an anonymous type.

The easiest way to understand this technique is to consider an example. The following code extracts some of the information from the BooksList.xml document and rearranges it into a different structure.

 

string xmlFile = Server.MapPath(“BooksList.xml”);

XDocument doc = XDocument.Load(xmlFile);

XDocument newDoc = new XDocument(

new XDeclaration(“1.0”, “utf-8”, “yes”),

new XElement(“Books”,

from Book in doc.Descendants(“Book”)

where (decimal)Book.Element(“Price”) < 14.90

select new XElement[] {

new XElement(“Book”,

new XAttribute(“Name”, (string)Book.Element(“Title”)),

new  XAttribute(“Writer”,(string) Book.Element(“Author”))

)

}

)

);

 

The first two statements open the original XML file and load it into an XDocument object. The third and final code statement does the rest—it creates a new XDocument and fills it with the transformed content.

The document starts with an XML declaration and is followed by the root element, which is named <Books>. The content for the node is an array of XElement objects, which are used to fill the <Books> element. The trick is that this array is constructed using a LINQ expression. This expression pulls out all the <Book> elements in the original documents (wherever they occur, using the Descendants() method) and filters for those that have Price element values less than 14.90. Finally, the select clause applies a projection that creates each nested XElement inside the <Books> element. Each nested Xelement represents a <Book> element, contains a Name attribute (which has the book title), and an Writer attribute (which has the book author).

The final result is as follows:

 

<Books>

<Book Name=” Steve Jobs” Writer=” Walter Isaacson” >

</Book>

<Book Name=” Tunnel Vision” Writer=” Gary Braver” >

</Book>

</Books>

 

The disadvantage of using LINQ to XML for transformation is that it’s not a standard technology, whereas XSLT definitely is. Furthermore, the logic is programmatic, which means you’ll need to recompile your code to change your transformation. Although the syntax of XSLT is more complex, its declarative model adds valuable flexibility if you need to share, reuse, or modify the transform.