Post

XML Processing & Transformation using C# and .NET.

In this post I will describe the basics of processing an XML using the classes avaialble in .NET. This article is part of multi-part series focusing on building a sustainable integration engine.

XML Processing & Transformation using C# and .NET.

The Importance of Data Transformation

In modern enterprise applications, data transformation is a critical process that enables systems to communicate, integrate, and operate cohesively. As organizations increasingly rely on diverse systems—ERP, CRM, databases, APIs, and third-party services—data often arrives in inconsistent formats. In large enterprises, it is critical that the data is accessible in a common format at one place. To make this data usable, it must be transformed into a standardized, canonical format.

In this artical, we will focus on understanding the foundational technology XML & .NET. These we are going to use to build our gateway engine in upcoming series of blog.

Understanding the Core Technologies

Lets start with understanding these technologies in detail.

What is XML?

XML (eXtensible Markup Language) is a markup language designed to store and transport data. It is both human-readable and machine-readable, making it ideal for data exchange between systems.

XML (eXtensible Markup Language) is a widely adopted standard for structured data representation.

Key Features

  • Self-descriptive: Data is wrapped in tags that describe its meaning.
  • Platform-independent: Works across different systems and technologies.
  • Hierarchical structure: Data is organized in a tree-like format.
  • Extensible: You can define your own tags and structure.

What is XSLT?

XSLT (eXtensible Stylesheet Language Transformations) is a declarative language designed specifically for transforming XML documents. It excels in:

  • Mapping one XML structure to another.
  • Filtering, sorting, and restructuring data.
  • Generating different output formats (XML, HTML, plain text, JSON).

It is part of the XSL (Extensible Stylesheet Language) family and works by applying transformation rules defined in an XSLT stylesheet.

How XSLT Works

  • XSLT uses templates to match elements in the source XML.
  • It applies XPath expressions to navigate and select nodes.
  • The transformation engine processes the XML and outputs a new document based on the rules.

Demo Preparation

Demo XML File

We will use the below XML file for all the below demo code. It contains list of authors and books. Below table describes each attribute of these entities

Books Entity

Column NameData TypeDescription
idStringUnique identifier for the book (e.g., B001)
titleStringTitle of the book
authorIdStringReference to the author’s ID (foreign key)
publishedYearIntegerYear the book was published
languageStringLanguage in which the book was originally written
isbnStringInternational Standard Book Number

Author Entity

Column NameData TypeDescription
idStringUnique identifier for the author (e.g., A001)
nameStringFull name of the author
nationalityStringCountry of origin
genreStringPrimary literary genre
birthYearIntegerYear the author was born
deathYearIntegerYear the author died (optional)
erDiagram
    AUTHORS {
        string id PK
        string name
        string nationality
        string genre
        int birthYear
        int deathYear
    }
    BOOKS {
        string id PK
        string title
        string authorId FK
        int publishedYear
        string language
        string isbn
    }
    AUTHORS ||--o{ BOOKS : writes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?xml version="1.0" encoding="UTF-8"?>
<library>
  <authors>
    <author id="A001" nationality="British" genre="Dystopian">
      <name>George Orwell</name>
      <birthYear>1903</birthYear>
      <deathYear>1950</deathYear>
    </author>
    <author id="A002" nationality="British" genre="Fantasy">
      <name>J.K. Rowling</name>
      <birthYear>1965</birthYear>
    </author>
    <author id="A003" nationality="Japanese" genre="Magical Realism">
      <name>Haruki Murakami</name>
      <birthYear>1949</birthYear>
    </author>
    <author id="A004" nationality="American" genre="Science Fiction">
      <name>Isaac Asimov</name>
      <birthYear>1920</birthYear>
      <deathYear>1992</deathYear>
    </author>
  </authors>

  <books>
    <book id="B001" authorId="A001" language="English">
      <title>1984</title>
      <publishedYear>1949</publishedYear>
      <isbn>9780451524935</isbn>
    </book>
    <book id="B002" authorId="A001" language="English">
      <title>Animal Farm</title>
      <publishedYear>1945</publishedYear>
      <isbn>9780451526342</isbn>
    </book>
    <book id="B003" authorId="A002" language="English">
      <title>Harry Potter and the Sorcerer's Stone</title>
      <publishedYear>1997</publishedYear>
      <isbn>9780439708180</isbn>
    </book>
    <book id="B004" authorId="A002" language="English">
      <title>Harry Potter and the Chamber of Secrets</title>
      <publishedYear>1998</publishedYear>
      <isbn>9780439064873</isbn>
    </book>
    <book id="B005" authorId="A002" language="English">
      <title>Harry Potter and the Prisoner of Azkaban</title>
      <publishedYear>1999</publishedYear>
      <isbn>9780439136365</isbn>
    </book>
    <book id="B006" authorId="A002" language="English">
      <title>Harry Potter and the Goblet of Fire</title>
      <publishedYear>2000</publishedYear>
      <isbn>9780439139601</isbn>
    </book>
    <book id="B007" authorId="A002" language="English">
      <title>Harry Potter and the Order of the Phoenix</title>
      <publishedYear>2003</publishedYear>
      <isbn>9780439358071</isbn>
    </book>
    <book id="B008" authorId="A002" language="English">
      <title>Harry Potter and the Half-Blood Prince</title>
      <publishedYear>2005</publishedYear>
      <isbn>9780439785969</isbn>
    </book>
    <book id="B009" authorId="A002" language="English">
      <title>Harry Potter and the Deathly Hallows</title>
      <publishedYear>2007</publishedYear>
      <isbn>9780545010221</isbn>
    </book>
    <book id="B010" authorId="A003" language="Japanese">
      <title>Kafka on the Shore</title>
      <publishedYear>2002</publishedYear>
      <isbn>9781400079278</isbn>
    </book>
    <book id="B011" authorId="A003" language="Japanese">
      <title>Norwegian Wood</title>
      <publishedYear>1987</publishedYear>
      <isbn>9780375704024</isbn>
    </book>
    <book id="B012" authorId="A003" language="Japanese">
      <title>1Q84</title>
      <publishedYear>2009</publishedYear>
      <isbn>9780307593313</isbn>
    </book>
    <book id="B013" authorId="A003" language="Japanese">
      <title>The Wind-Up Bird Chronicle</title>
      <publishedYear>1994</publishedYear>
      <isbn>9780679775430</isbn>
    </book>
    <book id="B014" authorId="A003" language="Japanese">
      <title>Hard-Boiled Wonderland and the End of the World</title>
      <publishedYear>1985</publishedYear>
      <isbn>9780679743460</isbn>
    </book>
    <book id="B015" authorId="A004" language="English">
      <title>Foundation</title>
      <publishedYear>1951</publishedYear>
      <isbn>9780553293357</isbn>
    </book>
    <book id="B016" authorId="A004" language="English">
      <title>Foundation and Empire</title>
      <publishedYear>1952</publishedYear>
      <isbn>9780553293371</isbn>
    </book>
    <book id="B017" authorId="A004" language="English">
      <title>Second Foundation</title>
      <publishedYear>1953</publishedYear>
      <isbn>9780553293364</isbn>
    </book>
    <book id="B018" authorId="A004" language="English">
      <title>Foundation's Edge</title>
      <publishedYear>1982</publishedYear>
      <isbn>9780553293388</isbn>
    </book>
    <book id="B019" authorId="A004" language="English">
      <title>Foundation and Earth</title>
      <publishedYear>1986</publishedYear>
      <isbn>9780553293425</isbn>
    </book>
    <book id="B020" authorId="A004" language="English">
      <title>Prelude to Foundation</title>
      <publishedYear>1988</publishedYear>
      <isbn>9780553278392</isbn>
    </book>
  </books>
</library>

Demo XLST File

The belwo file shows a typical transformation logic that we can use to generate a HTML table from given XML file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>
  <xsl:key name="booksByAuthor" match="book" use="@authorId"/>
  <xsl:template match="/">
    <html>
      <head>
        <title>Library Catalog</title>
        <style>
          table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
          th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
          th { background-color: #f2f2f2; }
          h2 { margin-top: 40px; }
        </style>
      </head>
      <body>
        <h1>Library Catalog</h1>
        <xsl:for-each select="library/authors/author">
          <xsl:variable name="authorId" select="@id"/>
          <xsl:if test="count(key('booksByAuthor', $authorId)) &gt; 0">
            <h2>
              <xsl:value-of select="name"/> 
              (<xsl:value-of select="@genre"/>, 
              <xsl:value-of select="@nationality"/>)
            </h2>
            <table>
              <tr>
                <th>Title</th>
                <th>Published Year</th>
                <th>Language</th>
                <th>ISBN</th>
              </tr>
              <xsl:for-each select="key('booksByAuthor', $authorId)">
                <tr>
                  <td><xsl:value-of select="title"/></td>
                  <td><xsl:value-of select="publishedYear"/></td>
                  <td><xsl:value-of select="@language"/></td>
                  <td><xsl:value-of select="isbn"/></td>
                </tr>
              </xsl:for-each>
            </table>
          </xsl:if>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

C# Support for XML and XSLT

Overview

C# and the .NET Framework provide robust, high-performance support for working with XML and XSLT. These capabilities are essential for building transformation pipelines, especially in enterprise applications. We will explore some of the most important classes and thier usage. This will give you a solid foundaiton to work on advance XML scenarios.

Key Namespaces and Classes

Below are some of the important namespaces in .NET. Depending upon your use case, these can be utilized in combination.

NamespacePurpose
System.XmlCore XML support (DOM, readers, writers)
System.Xml.XPathXPath querying support
System.Xml.XslXSLT transformation engine
System.Xml.SchemaXML Schema validation

Key .NET classes used in XML Processing & Transformation

  • XslCompiledTransform: Compiles XSLT stylesheets for fast, reusable transformations.
  • XslTransform: XSL transformation.
  • XmlReader / XmlWriter: Use this classes for forward-only, streaming access to XML documents. Ideal for large files.
  • XmlDocument: This provides a DOM based approach to load, modify & save the XML document. This is mostly used to manipulate document pre or post transformaiton.
  • XPathNavigator: This provides a read-only cursor for efficient XPath queries execution.

We will now see a sample code for each of these classes.

Using XslCompiledTransform class

In this case we will use XslCompiledTransform class to performs the transformaiton. Here -

  • We first load the XSLT file in the XslCompiledTransform instance.
  • We create a output stream using XmlWriter class. This will write output path.
  • Last we call the Transform method to actually do the transformaiton.

This code will perform the transformation and write an output to output.html file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static void UsingXslCompiledTransform()
{
    // Paths to the XML and XSLT files
    String xmlPath = "books.xml";
    String xsltPath = "transformation.xslt";
    String outputPath = "catalog.html";

    // Create the XslCompiledTransform and load the XSLT
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(xsltPath);

    // Transform the XML and output to HTML file
    using (XmlWriter writer = XmlWriter.Create(outputPath, xslt.OutputSettings))
    {
        xslt.Transform(xmlPath, writer);
    }

    Console.WriteLine($"Transformation complete. Output written to {outputPath}");
}

Using XslTransform class

Info: This is only for .NET Framework. This code will not work in .NET Core. I am including this code for the sake completeness but is no longer recommended.

This code also follows the same logic as earlier, it

  • Create XslTransform instance and loads it with XSLT transformation file
  • Create a XML reader and writer instances
  • Performs transformation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/// <summary>
/// Transforms an XML file into an HTML file using the legacy XslTransform class.
/// </summary>
/// <remarks>
/// XslTransform is obsolete and only available in .NET Framework, not .NET Core or .NET 5+.
/// This sample is for legacy reference only.
/// </remarks>
static void UsingXslTransform()
{
#pragma warning disable SYSLIB0016 // Type or member is obsolete
    String xmlPath = "books.xml";
    String xsltPath = "transformation.xslt";
    String outputPath = "catalog_xsltransform.html";

    XslTransform xslt = new XslTransform();
    xslt.Load(xsltPath);

    using (XmlReader reader = XmlReader.Create(xmlPath))
    using (XmlWriter writer = XmlWriter.Create(outputPath))
    {
        xslt.Transform(reader, null, writer);
    }

    Console.WriteLine($"Transformation complete. Output written to {outputPath}");
#pragma warning restore SYSLIB0016
}

Conclusion

.NET and XML offers a very elegant solution to build transformation component. We will take this idea to next level to build a custom integration and transformation engine. Be with me on this journey.

This post is licensed under CC BY 4.0 by the author.