DesignLiquido / xslt-processor

A JavaScript XSLT processor without native library dependencies
GNU Lesser General Public License v3.0
94 stars 30 forks source link

CDATA in xsl not working as expected #95

Open Kartonatic opened 1 month ago

Kartonatic commented 1 month ago

Hi! I'm trying to put js code in the xsl template but it is not able to resolve the CDATA tag within the xsl. You could use this code to test:

import { XmlParser, Xslt, XsltOptions } from 'xslt-processor';

// Transform template to HTML
const xsl = `
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" version="4.0" encoding="utf-8" omit-xml-declaration="yes" />
  <xsl:template match="/">
    <html>
      <head>
        <script type="text/javascript">
          <![CDATA[
          if (1 < 2) {}
        ]]>
        </script>
      </head>
      <body>
        <h1>
          <xsl:value-of select="ReportName"/>
        </h1>
        <p>
          <xsl:value-of select="GenerationDate"/>
        </p>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
    `;
const xml = `
<XampleXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ReportName>My first transformation in js</ReportName>
  <GenerationDate>01/06/2024</GenerationDate>
</XampleXml>
    `;

const options: XsltOptions = {
  cData: true,
  escape: false,
  selfClosingTags: false,
};
const xslt = new Xslt(options);
const xmlParser = new XmlParser();
xslt
  .xsltProcess(xmlParser.xmlParse(xml), xmlParser.xmlParse(xsl))
  .then((output) => {
    console.log(output);
  });
//OUTPUT: <html><head><script type="text/javascript"></script></head><body><h1>My first transformation in js</h1><p>01/06/2024</p></body></html>

As you can see, the content of the script (CDATA content) does not appear in the output.

Another curious thing is that if we add xsl:text around it, the following happens:

import { XmlParser, Xslt, XsltOptions } from 'xslt-processor';

// Transform template to HTML
const xsl = `
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" version="4.0" encoding="utf-8" omit-xml-declaration="yes" />
  <xsl:template match="/">
    <html>
      <head>
        <script type="text/javascript">
          <xsl:text disable-output-escaping="yes">
            <![CDATA[
          if (1 < 2) {}
        ]]>
          </xsl:text>
        </script>
      </head>
      <body>
        <h1>
          <xsl:value-of select="ReportName"/>
        </h1>
        <p>
          <xsl:value-of select="GenerationDate"/>
        </p>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
    `;
const xml = `
<XampleXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ReportName>My first transformation in js</ReportName>
  <GenerationDate>01/06/2024</GenerationDate>
</XampleXml>
    `;

const options: XsltOptions = {
  cData: true,
  escape: false,
  selfClosingTags: false,
};
const xslt = new Xslt(options);
const xmlParser = new XmlParser();
xslt
  .xsltProcess(xmlParser.xmlParse(xml), xmlParser.xmlParse(xsl))
  .then((output) => {
    console.log(output);
  });
//OUTPUT:
//
//
//
// if (1 < 2) {}
//
// <html><head><script type="text/javascript"></script></head><body><h1>My first transformation in js</h1><p>01/06/2024</p></body></html>

The script appears at the beginning of the resulting html.

Could you investigate to resolve that?

Thank you!

leonelsanchesdasilva commented 1 week ago

Hi @Kartonatic. Thanks for reporting.

I should be able to return to this issue in the next weeks.