Reputation: 33
Is there a way to escape or render Javascript in a xquery function?
Example:
xquery version "1.0-ml";
module namespace tagmanager = "tagmanager";
declare function tagmanager() { < noscript > < iframe src = "//www.googletagmanager.com/ns.html?id=[value]"
height = "0"
width = "0"
style = "display:none;visibility:hidden" > < /iframe></noscript >
< script > (function(w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({
'gtm.start': new Date().getTime(),
event: 'gtm.js'
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src =
'//www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'value'); < /script>
};
Upvotes: 3
Views: 506
Reputation: 5294
I've always used the approach of escaping problematic characters and treating the HTML as well-formed XML:
(1) escape the problematic characters like ampersands (&
> &
) and curly braces, which just need to be doubled: {
> {{
and }
> }}
(2) if serving up multiple elements, create a sequence: (<element1/>, <element2/>)
Applying that approach to this example:
(
<noscript>
<iframe src = "//www.googletagmanager.com/ns.html?id=[value]"
height = "0"
width = "0"
style = "display:none;visibility:hidden"></iframe>
</noscript>,
<script> (function(w, d, s, l, i) {{
w[l] = w[l] || [];
w[l].push({{
'gtm.start': new Date().getTime(),
event: 'gtm.js'
}});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src =
'//www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
}})(window, document, 'script', 'dataLayer', 'value');
</script>
)
That said, I like the CDATA approach - had never occurred to me before!
Upvotes: 2
Reputation: 3732
CDATA content does not need escaping. The example is obtuse because your generating HTML in an XML lanaguge, I suggest treating the whole thing as a string. Explicit CDATA constructor is only allowed withing an element so you need a wrapper. http://www.w3.org/TR/xquery/#doc-xquery-CDataSectionContents
Example:
xquery version "1.0-ml";
declare namespace html = "http://www.w3.org/1999/xhtml";
declare function local:tagmanager() as xs:string
{
<wrapper>
<![CDATA[
< noscript > < iframe src = "//www.googletagmanager.com/ns.html?id=[value]"
height = "0"
width = "0"
style = "display:none;visibility:hidden" > < /iframe></noscript >
< script > (function(w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({
'gtm.start': new Date().getTime(),
event: 'gtm.js'
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src =
'//www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'value'); < /script>
]]>
</wrapper>/string()
};
local:tagmanager()
Upvotes: 3
Reputation: 7335
One approach is to put the JavaScript in a text file read with a separate request (which is also beneficial for browser caching).
Another is to use a CDATA section for the content of an element, as in:
However, you still have to use ampersand escapes for the reserved characters ( < > ' " &) within the CDATA section.
Hoping that helps,
Upvotes: 1