Home > Back-end >  Passing node as parameter in msxsl:script javascript function from XSLT for-each doesn't work
Passing node as parameter in msxsl:script javascript function from XSLT for-each doesn't work

Time:11-11

I am using MSXML6 and I've set the AllowXsltScript to true in order to enable the usage of scripts in my VB program.

Given the following XML input:

<xml>
    <data>
        <row TEST_ATTRIBUTE_1="test1a" TEST_ATTRIBUTE_2="test2a"/>
        <row TEST_ATTRIBUTE_1="test1b" TEST_ATTRIBUTE_2="test2b"/>
        <row TEST_ATTRIBUTE_1="test1c" TEST_ATTRIBUTE_2="test2c"/>
    </data>
</xml>

The following XSL doesn't work as expected:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version = "1.0"
  xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:user="random">

  <msxsl:script language="javascript" implements-prefix="user" >
  <![CDATA[
  function getValue(node, attribute)
  {  
     var value;
     value = node.getAttribute(attribute);

     return value;
  }
 ]]>
  </msxsl:script>
  
  <xsl:template match="/">
    <xsl:apply-templates select="//data"/>
  </xsl:template>

  <xsl:template match="//data">
    <TBODY>
      <xsl:for-each select="row">
        <xsl:value-of select="user:getValue(this, 'TEST_ATTRIBUTE_1')"/>
      </xsl:for-each>
    </TBODY>
  </xsl:template>

</xsl:stylesheet>

The problem seems to be with passing in "this" for node inside for-each. More exactly when it's trying to do node.getAttribute(attribute); that's when it fails.

The error I'm getting is "The text associated with this error code could not be found. XML document must have a top level element." inside Visual Studio 2017 in my VB program using the MSXML2.DOMDocument60.transformNodeToObject API.

Note that I cannot use any online XSL parsers as they have the script functionality disabled by default.

Any thoughts on this?

Appreciate it!

CodePudding user response:

It should be user:getValue(., 'TEST_ATTRIBUTE_1'), to pass the row element node to the function; this does not make sense in XSLT/XPath, only in Java or JavaScript or C# perhaps.

However, that the node you pass in is not reflected to the extension script as a single DOM node, you might get a DOM selection list and need e.g. function getValue(selection, attributeName) { return selection[0].getAttribute(attributeName); } to access the first (and in this case single) item in that selection.

  • Related