Skip to content

Instantly share code, notes, and snippets.

@dfkaye
Last active May 18, 2024 01:39
Show Gist options
  • Save dfkaye/882796e70b12940a616fcb7434ec9ddd to your computer and use it in GitHub Desktop.
Save dfkaye/882796e70b12940a616fcb7434ec9ddd to your computer and use it in GitHub Desktop.
import XML source documents into XSLT using the document() function.
// 2 March 2024
// import XML source documents into XSLT using the document() function.
// example markup borrowed from
// https://www.abbeyworkshop.com/howto/xslt/document/
// parsing function defined in gist 19 June 2023,
// "Using XML, XSLT, XHR, to parse and serialize HTML in the browser",
// https://gist.github.com/dfkaye/94bc03241c4c3bf458ab0dc5d56b1958
// 17 May 2024
// shrunk the parse function further
async function parse({ text = "", type = "" }) {
var blob = new Blob([text], { type });
var url = URL.createObjectURL(blob);
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "document";
xhr.send();
return new Promise(function (resolve) {
xhr.onload = function () { resolve(xhr.response) };
});
}
/* build XML blobs and create object URLs for each. */
var url = [
`
<entry>
<name>john Doe</name>
<address>john doe's address</address>
</entry>
`,
`
<entry>
<name>cool Ness</name>
<address>cool ness's address</address>
</entry>
`,
`
<entry>
<name>third Man</name>
<address>third Man's address</address>
</entry>
`
].map(xml => {
var blob = new Blob([xml], { type: "application/xml" });
var url = URL.createObjectURL(blob);
return url;
})
/* refer to each URL in an XML list of "files" */
var listsrc = `
<?xml version="1.0" encoding="UTF-8"?>
<list>
<file url="${ url[0] }" />
<file url="${ url[1] }" />
<file url="${ url[2] }" />
</list>
`.trim();
console.log(listsrc);
/*
<?xml version="1.0" encoding="UTF-8"?>
<list>
<file url="blob:null/5fd868c9-aed3-43b1-bd2b-394f95c3a8e9" />
<file url="blob:null/639620de-925a-447d-ad01-bb4577a19879" />
<file url="blob:null/9f5bda6a-5a0d-49a1-94df-31b0475a099a" />
</list>
*/
/* XSL source with document() function in top template match */
var xslsrc = `
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<ul>
<xsl:for-each select="/list/file">
<!-- document() fetches url from @url attribute -->
<xsl:apply-templates select="document(@url)/entry" />
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="entry">
<li><xsl:apply-templates /></li>
</xsl:template>
<xsl:template match="name">
<b><xsl:value-of select="." /></b>
</xsl:template>
<xsl:template match="address">
<address><xsl:value-of select="." /></address>
</xsl:template>
</xsl:stylesheet>
`.trim();
/* test it out */
var xsl = await parse({ text: xslsrc, type: "xml" });
var xslt = new XSLTProcessor;
xslt.importStylesheet(xsl);
var xml = await parse({ text: listsrc, type: "html" });
var fragment = xslt.transformToFragment(xml, document);
document.body.replaceChildren(fragment);
console.log(document.body.firstElementChild.outerHTML);
/*
<ul><li>
<b>john Doe</b>
<address>john doe's address</address>
</li><li>
<b>cool Ness</b>
<address>cool ness's address</address>
</li><li>
<b>third Man</b>
<address>third Man's address</address>
</li></ul>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment