0

I have a XSL as below :

<xsl:template match="/">
    <xsl:variable name="vartext" select="''" />

....
             <th>
                <xsl:value-of select="$vartext"/>
              </th>

I set the value of vartext using js, as below :

node = this.xsldoc.selectSingleNode('//xsl:variable[...]']');
node.setAttribute('select', sometext);

Accordint to the https://www.w3schools.com/xml/ref_xsl_el_variable.asp, If the select attribute contains a literal string, the string must be within quotes.

But the variable might containt a value like this "'Hey d'text '".

So when I wan to transform my XML using the XSL provided, it does not work. I even tried to replace ' with \'.

Update:

I tried the scape single quote in xslt concat function before posting the question and it did not help me.

The way that I use XSL is as below :

var res = xsltDo(this.xmldoc, this.xsldoc, this.html_element, iOptionParent);

xsltDo = function (xml, xsl, target, iOptionParent) {
        try {
            if (!iOptionParent) target.innerHTML = "";
            var fragment = xml.transformNode(xsl);
            target.innerHTML += fragment;
            //$( window ).trigger( "XsltDone", [target] );

            if (window.AC !== undefined) {
                window.AC.onDomChange(target);
            }

            return true;
        }
        // si erreur on retourne une XsltError
        catch (err) {
            return new Error(err);
        }
    };
Babak Fakhriloo
  • 2,076
  • 4
  • 44
  • 80
  • 1
    If you are using `node.setAttribute` then you shouldn't have to worry about escaping, as that would only apply to the initial XSLT file before it is parsed and processed. I think you might need to explain more about the process you are using (for example, how are you reading and applying the XSLT), and explain exactly what you mean by "it does not work". Thanks! – Tim C May 17 '19 at 11:32
  • From the fragment you have shown, perhaps you should actually be using parameters (`xsl:param`) instead of trying to manipulate the XSLT in this way. – Tim C May 17 '19 at 11:33
  • @R3tep I do not concatenate the strings so the solution does not work for me. – Babak Fakhriloo May 17 '19 at 12:01
  • 1
    I wonder what you are really trying to achieve? Is it really necessary to do this by modifying the source stylesheet? Can't it by done by supplying a value to an `xsl:param` parameter? Remember that modifying source always creates a risk of injection attacks unless you take immense care. – Michael Kay May 17 '19 at 12:01
  • @MichaelKay I stuck with the solution because it is legacy code, in the mean time I am new to XSL. So I do not know whether it could be done by xsl:param and javascript. – Babak Fakhriloo May 17 '19 at 12:04
  • 1
    @BabakFakhriloo the proper mechanism to parametrize an XSLT transformation is to use `xsl:param` declaration as suggested by Dr. Kay. Although not standard, in Javascript there is a good cross browser interface [XSLTProcessor](https://developer.mozilla.org/en-US/docs/Web/API/XSLTProcessor). – Alejandro May 17 '19 at 13:04

1 Answers1

1

This was a bit too long to write in comments, but supposed you had someText set to just "Hey". If you are doing just this

 node.setAttribute('select', someText);

Then this is the same as doing this directly in the XSLT

 <xsl:variable name="vartext" select="Hey" />

This will select an element called "Hey", not the text literal "Hey"

What you can do is this...

 node.setAttribute('select', '"' + someText + '"');

This will be the equivalent of doing this in XSLT

 <xsl:variable name="vartext" select='"Hey"' />

This will also work if you have apostrophe in your someText variable, and there will be no need to escape it in javascript. However, it will fail if you have a quote mark " in someText.

What would be easier, to cope with both apostrophes and quotation marks, is to remove the select attribute, and add the text as a child node

node.removeAttribute("select");
node.appendChild(xsl.createTextNode(someText));

This would be the same as doing this...

<xsl:variable name="vartext">Hey 'Text "It works!"</xsl:variable>

Of course, what you should really be doing is changing the XSLT to use parameters. Not least because "selectSingleNode" is only supported in Internet Explorer, I believe.

If you can do change the XSLT to use parameters, there are other questions on StackOverflow to show you have to set parameters in Javascript. See How to pass parameter to XSLT from Javascript function for example.

Tim C
  • 70,053
  • 14
  • 74
  • 93