Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self closing tags in xsl method: xml

I am working with a site that uses "xsl method:xml" to create html templates. However, I am running into an issue with the tag self-closing when the html page is rendered by the xsl engine.

<div></div> transforms to => <div/>

This problem is compounded by the fact that the method needs to stay xml, or the other components of the page will not render correctly.

Any ideas on how tell xsl to make a special exception for the node <div>?

This question is similar to this question, except I want to keep the method:xml. XSLT self-closing tags issue

like image 375
justonpoints Avatar asked Jan 15 '23 00:01

justonpoints


2 Answers

It is not available by default with method=xml. You can handle it in a couple of ways:

Option 1 - switch to method=xhtml

If you can't switch to method=xml, and you are using XSLT 2.0 parser, maybe you can try method=xhtml?

<xsl:output method="xhtml" indent="yes" />

This will make your closing tags to be rendered.

Option 2 - add empty space to 'div' tag

Alternatively just add <xsl:text> </xsl:text> (with one space in between tags) to make your <div> not empty (of course if space there is okay with you).

Consider following XML:

<div></div>

When transformed with:

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

  <!-- output is xml -->
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="div">
    <div>
      <!-- note space here -->
      <xsl:text> </xsl:text>
      <xsl:value-of select="text()" />
    </div>
  </xsl:template>
</xsl:stylesheet>

It produces output:

<?xml version="1.0" encoding="UTF-8"?>
<div> </div>
like image 165
kamituel Avatar answered Jan 19 '23 12:01

kamituel


I have had the same issue. The problem is the XmlTextWriter which only messes up the html. Try the following code:

public static string Transform(string xmlPath, string xslPath, XsltArgumentList xsltArgumentList)
    {
        string rc = null;
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            XPathDocument myXPathDoc = new XPathDocument(xmlPath);
            XslCompiledTransform myXslTrans = new XslCompiledTransform();
            myXslTrans.Load(xslPath, new XsltSettings(true, true), null);
            myXslTrans.Transform(myXPathDoc, xsltArgumentList, ms);
            ms.Position = 0;
            using (System.IO.TextReader reader = new System.IO.StreamReader(ms, Encoding.UTF8))
            {
                rc = reader.ReadToEnd();
            }
        }
        return rc;
    }

I use the XsltArgumentList to pass information to the xslt. If you do not need to pass arguments to your xslt, you may call the method like this:

string myHtml = Transform(myXmlPath, myXslPath, new XsltArgumentList());
like image 27
Håkan Avatar answered Jan 19 '23 12:01

Håkan