Glenn Carver
Glenn Carver

Reputation: 135

Prevent XSLT from removing end tags from empty nodes

I have this XSLT stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="no" />

    <xsl:template match="/">
        <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html></xsl:text>
        <xsl:call-template name="test" />
    </xsl:template>

    <xsl:template name="test">
        <html>

            <head>
                <link rel="stylesheet" href="style.css" />
                <script type="text/javascript" src="jquery.min.js"></script>
            </head>

            <body>
                <p>test</p>
            </body>

        </html>
    </xsl:template>

</xsl:stylesheet>

In Visual Studio 2019 I'm trying to code in C# and use XslCompiledTransform to transform this stylesheet to HTML code.

// XSLT settings (that turns on the usage of 'document()' directive)
XsltSettings settings = new XsltSettings(true, true);
// Instantiate the transformer (enabled debug)
XslCompiledTransform xslt = new XslCompiledTransform(true);
// Load the data from XML
XPathDocument xml_config = new XPathDocument("input.xml");
// Load XSLT stylesheet
xslt.Load("stylesheet.xslt", settings, null);
// Prepare to write output
XmlTextWriter myWriter = new XmlTextWriter("output.html", Encoding.UTF8);
// Transform XML to HTML via XSLT
xslt.Transform(xml_config, null, myWriter);

Resulting output: (Broken html)

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="style.css" />
    <script type="text/javascript" src="jquery.min.js" />
</head>

<body>
    <p>test</p>
</body>

</html>

Xslt transformer breaks HTML code by making tag a self closing for some reason. This makes body and p tags a child of script - hence not rendering it.

One solution is to add &#160; to script tag so it is no longer considered empty and doesn't become self-closed <script type="text/javascript" src="jquery.min.js">&#160;</script> It's not a solution however since it's not always possible to edit the incoming XML file. Is there any other solution to this? Am I missinf something in my cs source code? Or do I have to use a non-default XSLT transformer ?

Somewhere this has been suggested to be put to the stylesheet: <xsl:output method="html" /> But this just doesn't work for some reason

Upvotes: 1

Views: 184

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167516

You shouldn't use the XmlTextWriter as the destination but simply use xslt.Transform("input.xml", "output.html"), that way the XSLT processor is in charge of the serialization and can apply your xsl:output settings.

If you really need an XmlWriter as the destination make sure you create one with e.g. XmlWriter.Create("output.html", xslt.OutputSettings).

Upvotes: 2

Related Questions