How can make an XSLT Javascript extension function return a node-set?

☆樱花仙子☆ 提交于 2019-11-27 08:17:01

问题


Is there a simple way to have an extension function in XSLT 1.0 written in javascript return a node-set?
I could create a new java class for this, but I would rather just put some code in the script itself.
When this can be done in another scripting language supported by all or most XSLT processors (VB script? Groovy? C#?), then that's OK too of course.

I have the following simple script:

<msxsl:script language="JScript" implements-prefix="custom">
    function xml (input) {
        var x = input.split(";");
        return x.toString();
    }
</msxsl:script>

which returns a string, and hence no problem calling the function in Xpath expressions.
What I would like to have, is a node-set result. But when I change my script to

<msxsl:script language="JScript" implements-prefix="custom">
    function xml (input) {
        var x = input.split(";");
        return x;
    }
</msxsl:script>

then calling the function gives an error because the array is not automatically converted to a node-set.

I looked at arrays-with-java-xslt-extensions but that's more in the line of creating a new class for this, which I wish to avoid for now.

So which statements should be added to the script in order to transform the array into a node-set, allowing the function call to be used in Xpath expressions?


回答1:


Here is an example that should work with MSXML 6 as long as run in a mode allowing script in XSLT to implement extension functions. The stylesheet code is as follows:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:ms="urn:schemas-microsoft-com:xslt"
  xmlns:my="http://example.com/my"
  exclude-result-prefixes="ms my">

  <xsl:output method="html" version="5.0"/>

  <ms:script language="JScript" implements-prefix="my">
  <![CDATA[
  function tokenize (input) {
    var doc = new ActiveXObject('Msxml2.DOMDocument.6.0');
    var fragment = doc.createDocumentFragment();
    var tokens = input.split(';');
    for (var i = 0, l = tokens.length; i < l; i++)
    {
      var item = doc.createElement('item');
      item.text = tokens[i];
      fragment.appendChild(item);
    }
    return fragment.selectNodes('item');
  }
  ]]>
  </ms:script>

  <xsl:template match="/">
    <html>
      <head>
        <title>Example</title>
      </head>
      <body>
        <h1>Example</h1>
        <ul>
          <xsl:apply-templates select="my:tokenize('Kibology;for;all')"/>
        </ul>
      </body>
    </html>
   </xsl:template>

   <xsl:template match="item">
     <li>
       <xsl:value-of select="."/>
     </li>
   </xsl:template>

</xsl:stylesheet>



回答2:


If you want nodes returned, you'll have to create the nodes yourself, using DOM interfaces. I suspect (from memory) that if you return a DOM NodeList from your javascript function it will be treated by the calling XPath code as an XPath nodeset - though you'll have to check the spec carefully for details about how duplicate nodes and document order are handled.

Any questions about XSLT java or javascript extensions need to say what product(s) you are talking about, because there are no standards here.



来源:https://stackoverflow.com/questions/10222750/how-can-make-an-xslt-javascript-extension-function-return-a-node-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!