Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of duplicate keys in xsl:map #169

Closed
michaelhkay opened this issue Sep 30, 2022 · 5 comments
Closed

Handling of duplicate keys in xsl:map #169

michaelhkay opened this issue Sep 30, 2022 · 5 comments
Labels
Enhancement A change or improvement to an existing feature Requires confirmation Text is in the current draft but requires WG review and acceptance XSLT An issue related to XSLT

Comments

@michaelhkay
Copy link
Contributor

The draft specifications include proposals to enhance the handling of duplicate key values in xsl:map. This issue seeks WG endorsement of these changes.

See XSLT section 21.2.1

map:merge currently provides a set of fixed "policy" options for handling of duplicates; xsl:map always raises an error.

Rather than adopt the fixed set of policies in map:merge, I propose that xsl:map should accept a callback function to process duplicates. For example, forming a sequence-concatenation of the values can be achieved using on-duplicates="op(',')". This approach allows all the options provided by map:merge, and more; for example the duplicate entries can be combined using string-join() if so desired.

@michaelhkay michaelhkay added XSLT An issue related to XSLT Enhancement A change or improvement to an existing feature labels Sep 30, 2022
@graydon2014
Copy link

https://www.saxonica.com/papers/xmlprague-2020mhk.pdf says "the required
type is a function with arity 2" and seems to presume that there will be
only two duplicates, rather than potentially arbitrarily many
duplicates. (But of course the proposal may have evolved since.)

Would

<xsl:map on-duplicates="function($x as item()+, $y){head($x)}">

work?

Would

<xsl:map on-duplicates="function($x as item()+, $y){$x[$y]}">

? (I have no idea why I'd want to do the second one, but it leaps to mind
with a required arity of 2.)

I have fairly often wanted to group all the examples of something under
a key; everything with a date in June, everything with a level depth of
three, stuff like that. It'd be extremely convenient if
xsl:map/@on-duplicates allowed for this kind of "everything with this
key maps under this key" use case.

@michaelhkay
Copy link
Contributor Author

The idea is to support a single-pass operation where, when you encounter a duplicate, you decide what to do with it there and then. The two arguments are (a) the current value (which may result from previous processing of duplicates), and (b) the new value, and you're expected to combine them into a new current value. If you want to build a sequence containing all the values you can use function{$x,$y){$x, $y}. In that sense it's rather like fold-left where you build the result incrementally by processing one item at a time and combining that item with the result of previous processing.

@graydon2014
Copy link

I think I'm thinking of the equivalent of use-any on map:merge(), something like

<xsl:variable as="map(*)" name="parasByTypes">
    <xsl:map on-duplicates="use-any">
      <xsl:apply-templates select="//paragraph" />
    </xsl:map>
  </xsl:variable>
  
  <xsl:template match="paragraph">
    <xsl:map-entry key="@class" select="." />
  </xsl:template>

And I'm not sure how I'd do that with current value and new value when there are multiple @class values on the paragraphs.

It is entirely reasonable to tell me not to expect to sneak grouping into how on-duplicates works, though the use-any for map:merge() does seem to handle this case.

@michaelhkay
Copy link
Contributor Author

The effect of use-any is to select any one of the duplicates at the processor's discretion. I suspect you really want the combine option, and that's achieved by on-duplicates="function{$x,$y){$x, $y}". This gives you a map entry containing the sequence-concatenation of all the values supplied for the key.

@michaelhkay michaelhkay added Bug Something that doesn't work in the current specification Requires confirmation Text is in the current draft but requires WG review and acceptance and removed Bug Something that doesn't work in the current specification labels Jul 12, 2023
@ndw
Copy link
Contributor

ndw commented Nov 28, 2023

The group accepted this as the status quo at meeting 056.

@ndw ndw closed this as completed Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement A change or improvement to an existing feature Requires confirmation Text is in the current draft but requires WG review and acceptance XSLT An issue related to XSLT
Projects
None yet
Development

No branches or pull requests

3 participants