.NET - Transform XML Data with XSLT

Raymond Raymond event 2021-09-11 visibility 2,069 comment 2
more_vert

Before JSON became the most popular data transfer format on Internet, XML was commonly used in many web applications. There were two very commonly use cases:

  • AJAX to retrieve XML data and then transform it to HTML to display on website. JavaScript can call ActiveX control to transform XML using XSLT. 
  • Use XSLT (itself is also an XML document) to transform XML data in server to other formats like HTML. This technique was very popular in early stages (2000s) to build template engine.

This article will provide XSLT (Extensible Stylesheet Language Transformation) example to transform XML to HTML using C#.

Sample XML data

We will use Kontext's RSS feed (XML based) as input data and transform is as HTML in a ASP.NET Core Razor application.

Data URL: https://kontext.tech/api/flex/rss.

Save the file as kontext.xml.

Sample code

Create project

Create a sample project using the following code:

mkdir dotnetxslt
cd .\dotnetxslt\  
dotnet new razor

Add kontext.xml

Add kontext.xml into project home folder as Embedded resource.

Create kontext.xsl

Create a file named kontext.xsl in project folder with the following content:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:template match="rss/channel">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous" />
  <h1>
   <xsl:element name="a">
    <xsl:attribute name="href">
     <xsl:value-of select="link"/>
    </xsl:attribute>
    <xsl:value-of select="title"/>
   </xsl:element>
  </h1>
  <div class="row row-cols-1 row-cols-md-3 g-4">
   <xsl:apply-templates select="item"/>
  </div>
 </xsl:template>
 <xsl:template match="item">
  <div class="col">
   <div class="card shadow-sm">
    <div class="card-body">
     <h5 class="card-title">
      <xsl:element name="a">
       <xsl:attribute name="href">
        <xsl:value-of select="link"/>
       </xsl:attribute>
       <xsl:attribute name="class">
        <xsl:text>text-dark text-decoration-none</xsl:text>
       </xsl:attribute>
       <xsl:value-of select="title"/>
      </xsl:element>
     </h5>
     <div class="card-text">
      <xsl:value-of select="description"/>
     </div>
     <span class="badge bg-primary">
      <xsl:value-of select="category"/>
     </span>
    </div>
   </div>
  </div>
 </xsl:template>
</xsl:stylesheet>

Set the file property as Embedded resource.

The above XSL document can transform RSS feed XML data as HTML. For each item, a Boostrap card element will be created. 

Update Index.cshtml.cs

Open Index.cshtml.cs file and add the following code to OnGet function.

public void OnGet()
    {
        // Load the style sheet.
        XslCompiledTransform xslt = new();
        var assembly = Assembly.GetExecutingAssembly();
        var assemblyName = assembly.GetName().Name;
        var xslResourcePath = $"{assemblyName}.kontext.xsl";
        var xmlResourcePath = $"{assemblyName}.kontext.xml";
        using var stream = assembly.GetManifestResourceStream(xslResourcePath);
        using var styleReader = XmlReader.Create(stream);
        xslt.Load(styleReader);

        using var dataStream = assembly.GetManifestResourceStream(xmlResourcePath);
        using var dataReader = XmlReader.Create(dataStream);
        using var sw = new StringWriter();
        xslt.Transform(dataReader, null, sw);
        HtmlOutput = sw.ToString();
    }

Update Index.cshtml

Update the Razor page with the following content:

@page
@model IndexModel
@{
    ViewData["Title"] = "XSLT Example in .NET";
}

@Html.Raw(Model.HtmlOutput)

Run the application

Run the application and the following page will show:

2021091182953-image.png

References

Read Embedded Assembly Resource Files in .NET

XslCompiledTransform Class 

More from Kontext
comment Comments
C Cemal Şener

Cemal access_time 3 years ago link more_vert

Model.HtmlOutput not exists in razor ?

Raymond Raymond

Raymond access_time 3 years ago link more_vert

You can define it as a property in the page model class.

Please log in or register to comment.

account_circle Log in person_add Register

Log in with external accounts