Home > Mobile >  C# XSLT transformer uses self closing HTML tags which are invalid
C# XSLT transformer uses self closing HTML tags which are invalid

Time:03-05

Using C#, I want to transform an xml string to an html string with xslt. However, some tags are transformed as self closing. Actually, this is a duplicate of XSLT self-closing tags issue and Prevent XslCompiledTransform from using self-closing tags . Unfortunately, could not make it work with the answers given to them. Below is a minimal fiddle.

https://dotnetfiddle.net/zsqent

Current output is

<div>
  <div  />
  <i  />
</div>

whereas I need it to be

<div>
  <div ></div>
  <i ></i>
</div>

In case fiddle gets deleted, here is a copy of it

Using C#, I want to transform an xml string to an html string with xslt. However, some tags are transformed as self closing. Actually, this is a duplicate of https://stackoverflow.com/questions/887739/xslt-self-closing-tags-issue and https://stackoverflow.com/questions/7153938/prevent-xslcompiledtransform-from-using-self-closing-tags . Unfortunately, could not make it work with the answers given to them. Below is a minimal fiddle.

https://dotnetfiddle.net/coEYKm

Current output is

<div>
  <div  />
  <i  />
</div>

whereas I need it to be

<div>
  <div ></div>
  <i ></i>
</div>

In case fiddle gets deleted, here is a copy of it

using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Xsl;
                    
public class Program
{
    public static void Main()
    {
        var xml = @"<a href=""#"" target=""_blank"">Click here</a>";
        var xsl = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
    <xsl:strip-space elements=""*"" />
    <xsl:template match=""/"">
        <div>
            <div test""></div>
            <i test""></i>
        </div>
    </xsl:template>
</xsl:stylesheet>";
        
        var html = TransformXml(xml, xsl);
        
        Console.WriteLine(html);
    }
    
    public static string TransformXml(string xml, string xslt)
    {
        var transformedDocument = new XDocument();

        using (var xsltStringReader = new StringReader(xslt))
        {
            var xmlReaderSettings = new XmlReaderSettings();
            xmlReaderSettings.DtdProcessing = DtdProcessing.Parse;
            using (XmlReader xsltReader = XmlReader.Create(xsltStringReader, xmlReaderSettings))
            {
                var transformer = new XslCompiledTransform();
                transformer.Load(xsltReader);
                using (var xmlStringReader = new StringReader(xml))
                {
                    using (XmlReader xmlReader = XmlReader.Create(xmlStringReader, xmlReaderSettings))
                    {
                        using (XmlWriter newDocumentWriter = transformedDocument.CreateWriter())
                        {
                            transformer.Transform(xmlReader, newDocumentWriter);
                        }
                    }
                }
            }
        }

        return transformedDocument.ToString();
    }
}

CodePudding user response:

Please try the following solution.

You can use single apostrophes for the XSLT attributes.

(1) XSLT output clause should be as follows:

<xsl:output indent='yes' media-type='text/html' method='html' omit-xml-declaration='yes' encoding='UTF-8' />

(2) Important parameter to use: xsl.OutputSettings. Otherwise, the XSLT settings are not taken into account.

c#

public static string TransformXml(string xml, string xslt)
{
    string output = String.Empty;

    using (StringReader srt = new StringReader(xslt))
    using (StringReader sri = new StringReader(xml))
    {
        using (XmlReader xrt = XmlReader.Create(srt))
        using (XmlReader xri = XmlReader.Create(sri))
        {
            XslCompiledTransform xsl = new XslCompiledTransform();
            xsl.Load(xrt);
            using (StringWriter sw = new StringWriter())
            using (XmlWriter xwo = XmlWriter.Create(sw, xsl.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
            {
                xsl.Transform(xri, xwo);
                output = sw.ToString();
            }
        }
    }

    return output;
}
  • Related