Skip to content

Help implementing last(), position() functions for XSLT #683

@egh

Description

@egh

Hi,

For my XSLT 2 processor, https://github.com/egh/xjslt, I would like to fix the implementation of last() and position(). The behavior is a little tricky, though.

For instance, this stylesheet:

<?xml version="1.0" encoding="UTF-8" ?>
<t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <t:template match="/">
    <out>
      <t:for-each select="/doc/foo">
        <t:value-of select="position()"/>
      </t:for-each>
    </out>
  </t:template>
</t:transform>

when applied to:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
  <foo/><bar/>
  <foo/><bar/>
  <foo/><bar/>
</doc>

should output:

<?xml version="1.0" encoding="UTF-8"?><out>123</out>

In contrast, for instance, the stylesheet:

...
      <t:for-each select="/doc/element()">
        <t:if test="local-name() = 'foo'">
          <t:value-of select="position()"/>
        </t:if>
      </t:for-each>

would output 135. In other words, the position() (and last()) depend on the for-each xpath and what was selected there.

In order to do this with my implementation, I need to either be able:

  1. to pass in something to evaluateXPath* functions to override the dynamicContext.contextSequence, or
  2. to override the position() and last() functions in some cases, i.e. when the contextItem is the same as the contextNode I passed in (and so I can calculate these values based on the node set being processed). But this means both:
    a. I need access to the contextItem and:
    b. Ideally, I need to pass computation to the built in implementation if the contextItem is not the contextNode I passed in.
  3. something else that I haven't thought of?

(1) is probably the easiest solution from my point of view, but I don't know if this is feasible.

I am happy to implement a solution to this, but I wanted to get a sense of what the best solution might be.

Thank you for your help! Let me know what other info might help you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions