在 msxsl 中将节点作为参数传递:来自 XSLT for-each 的脚本 javascript 函数不起作用

Posted

技术标签:

【中文标题】在 msxsl 中将节点作为参数传递:来自 XSLT for-each 的脚本 javascript 函数不起作用【英文标题】:Passing node as parameter in msxsl:script javascript function from XSLT for-each doesn't work 【发布时间】:2021-12-22 01:28:22 【问题描述】:

我正在使用 MSXML6,并且我已将 AllowXsltScript 设置为 true,以便在我的 VB 程序中启用脚本。

给定以下 XML 输入:

<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>

以下 XSL 无法按预期工作:

<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>

问题似乎在于在 for-each 中为节点传递“this”。更准确地说,当它尝试执行 node.getAttribute(attribute); 时,它会失败。

我得到的错误是“找不到与此错误代码关联的文本。XML 文档必须具有***元素。”在我的 VB 程序中使用 MSXML2.DOMDocument60.transformNodeToObject API 在 Visual Studio 2017 中。

请注意,我不能使用任何在线 XSL 解析器,因为它们默认禁用脚本功能。

对此有什么想法吗?

欣赏!

【问题讨论】:

应该是user:getValue(., 'TEST_ATTRIBUTE_1'),将row元素节点传递给函数。 this 在 XSLT/XPath 中没有意义,也许只有在 Java、JavaScript 或 C# 中。但是,我不确定您传入的节点是否作为 DOM 节点反映到扩展脚本中,您可能会获得 DOM 选择并需要例如function getValue(selection, attributeName) return selection[0].getAttribute(attributeName); 。查看 MSXML SDK 了解详细信息,如果无法解决,请回发。 @MartinHonnen 你确实是对的!必须通过'。而不是“this”,然后使用“[0]”访问它,因为它是作为列表发送的。我试过使用'。但我从来没有想过这是作为列表发送的,所以谢谢你! 我将评论变成了答案,以便您可以接受并将问题标记为已解决。 【参考方案1】:

应该是user:getValue(., 'TEST_ATTRIBUTE_1'),将行元素节点传递给函数; this 在 XSLT/XPath 中没有意义,也许只有在 Java、JavaScript 或 C# 中。

但是,您传入的节点不会作为单个 DOM 节点反映到扩展脚本中,您可能会获得一个 DOM 选择列表并需要例如function getValue(selection, attributeName) return selection[0].getAttribute(attributeName); 访问该选择中的第一个(在本例中为单个)项目。

【讨论】:

以上是关于在 msxsl 中将节点作为参数传递:来自 XSLT for-each 的脚本 javascript 函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Google Charts - 在javascript中将数据作为变量传递

将 XML 作为参数传递和解析到 XSLT 2.0

利用MSXSL.exe绕过AppLocker应用程序控制策略

如何在 CloudFormation 中将字符串列表作为参数传递?

在 msxsl 中使用程序集和命名空间的问题

XSL以xsl param作为参数运行