0

I am using LWC framework to develop the component. It's built on ES6 Standard. I am trying to use XSLTProcessor for one of my requirements but it's giving me an error.

Failed to construct 'XSLTProcessor': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

Code:

import { LightningElement } from 'lwc';

export default class DisplayReport extends LightningElement {
    handleOnClick(){        
        if(window.XSLTProcessor){
            console.log('XSLTProcessor TRUE')// Working
            try
            {
            var xsltProcessor = new window.XSLTProcessor();
            console.log('XSLTProcessor WORKING') // Not coming here
            }
            catch(e){
                console.log(e.message); //Error displayed
            }
        }
        if(window.DOMParser){
            console.log('DOMParser TRUE')
            try
            {
            var parser = new window.DOMParser();
            console.log('DOMParser WORKING') //This is working
            }
            catch(e){
                console.log(e.message); //No Errors
            }
        }
    }
}

I am not sure why XSLTProcessor is not working but DOMParser is working.

Shaggy
  • 5,422
  • 28
  • 98
  • 163
  • Is that happening in a particular browser? With a particular version of lwc? I was not familiar with it but when I try some code using XSLTProcessor at https://developer.salesforce.com/docs/component-library/tools/playground it seems to work fine in Google Chrome, at least when I use `
    ` for the div I want to insert the XSLT result fragment into.
    – Martin Honnen Oct 25 '20 at 14:25
  • This is happening in all browsers. You will see this error only when you add this custom component to salesforce page layout. – Shaggy Oct 25 '20 at 16:45

1 Answers1

1

For me at https://developer.salesforce.com/docs/component-library/tools/playground it works to have e.g. my-button.html as

<template>
    <div>
        <input type="button" value="test" onclick={handleClick}>
        <div class="xslt-output" lwc:dom="manual"></div>
    </div>
</template>

and my-button.js as

import { LightningElement } from 'lwc';

export default class MyButton extends LightningElement {

  handleClick() {
      const xsltProc = new XSLTProcessor();
      const xsltCode = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="list">
    <section>
      <h2>XSLTProcessor test</h2>
      <ul style="list-style-type: disc;">
        <xsl:apply-templates/>
      </ul>
    </section>
  </xsl:template>
  <xsl:template match="item">
    <li>
      <xsl:apply-templates/>
    </li>
  </xsl:template>
</xsl:stylesheet>`;
      const xmlCode = `<list>
    <item>foo</item>
    <item>bar</item>
  </list>`;
      const domParser = new DOMParser();
      const xsltDoc = domParser.parseFromString(xsltCode, 'application/xml');
      const xmlDoc = domParser.parseFromString(xmlCode, 'application/xml');
      xsltProc.importStylesheet(xsltDoc);

      const container = this.template.querySelector('div.xslt-output');

      container.appendChild(xsltProc.transformToFragment(xmlDoc, container.ownerDocument));
  }
}

then inside of app.html I can use <c-my-button></c-my-button> and on clicking the button the XSLT is executed and its result is inserted.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110