XML file with attached styles in XSL styles not getting applied in Angular

Viewed 49

I have created a tool which takes user input and on click on Save, generates a XML file and saves it in the assets folder. I have also created a XSL file to create a template and apply style which is saved in the assets folder as well.

Behavior is to display the xml file with the applied styles of xsl file inside the HTML page, but xml files are getting displayed inside the page without the styles applied. Below are the code for reference:

generate-xml.component.ts

onGenerateXMLClicked() {    
    const doc = document.implementation.createDocument("", "", null);
    const mainElem = doc.createElement("catalog");    
    const titleElem = doc.createElement("title");
    titleElem.textContent = 'Empire Burlesque';    
    const artistElem = doc.createElement("artist");
    artistElem .textContent = 'Bob Dylan';    
    const countryElem = doc.createElement("country");
    countryElem.textContent = 'USA';    
    mainElem.appendChild(titleElem);
    mainElem.appendChild(artistElem );
    mainElem.appendChild(countryElem);    
    var str_data = 'data:text/xml;charset=utf-8,' + encodeURIComponent(mainElem.outerHTML);    
    var anchor = document.createElement('a');
    anchor.setAttribute("href", str_data);
    anchor.setAttribute("download", 'world.xml');
    anchor.click();
    anchor.remove();
  }

world.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="./template.xsl"?>
<catalog>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
</catalog>

template.xsl

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

display-xml.html

<div [innerHTML]="myTemplate"></div>

display-xml.ts

ngOnInit() {

    fetch('/assets/data/world.xml').then(res => res.text()).then(data => {
      this.myTemplate = this.sanitizer.bypassSecurityTrustHtml(data);

      const parser = new DOMParser();
      const xml = parser.parseFromString(data, 'application/xml');
      const questionSet = xml.documentElement;
      
      this.myTemplate = this.sanitizer.bypassSecurityTrustHtml(data);

    });
  }

Note: if i open the xml file manually from chrome, it shows with the applied styles like the below image: enter image description here

If if I do ng serve and load the component, it shows like the below image: enter image description here

1 Answers

Well, you're not loading or processing the XSL. You need to parse both XML files, and then you also need to import XSL style with XSLTProcessor

After that, you can sanitize HTML element with Angular:

try this, I've added (a rough) fetch and parse methods.

  async getAsset(file: string): Promise<string> {
    const res = await fetch(file);
    const data = await res.text();
    return data;
  }

  parse(data: string): HTMLElement {
    const parser = new DOMParser();
    const xmlNode = parser.parseFromString(data, 'application/xml');
    const el = xmlNode.documentElement;
    return el;
  }

  async ngOnInit() {

    const xml = await this.getAsset('/assets/data/world.xml');
    const style = await this.getAsset('/assets/data/template.xsl');

    const xmlEl = this.parse(xml);
    const styleEl = this.parse(style);

    const xsltProcessor = new XSLTProcessor();
    xsltProcessor.importStylesheet(styleEl);
    const resultDocument = xsltProcessor.transformToDocument(xmlEl);

    this.myTemplate = this.sanitizer.bypassSecurityTrustHtml(resultDocument.firstElementChild?.innerHTML ?? '')

  }
Related