Re: [xsl] Finding Only Initial Following Siblings That Meet Some Criteria

Subject: Re: [xsl] Finding Only Initial Following Siblings That Meet Some Criteria
From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 5 Feb 2020 23:43:00 -0000
I like the use of xsl:iterate here--it seems to be a clean match for the



Eliot Kimber

o;?On 2/5/20, 5:14 PM, "Michael Kay mike@xxxxxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

    I think the ability to select items from a sequence until some condition
is true is something that's always been far too difficult.
    In my paper for XML Prague next week I propose:

      function($n){$n/@outputclass != $this/@outputclass})

    as a function that selects everything in a sequence up to, and excluding,
the first item where some condition is true.

    You could consider implementing this function using xsl:iterate:

    <xsl:function name="f:items-before" as="item()*">
      <xsl:param name="in" as="item()*"/>
      <xsl:param name="predicate" as="function(item()) as xs:boolean"/>
      <xsl:iterate select="$in">
          <xsl:when test="$predicate(.)">
             <xsl:sequence select="."/>

    And I've always thought a following-sibling-or-self axis would be handy,
though the name is horrendous.

    Michael Kay

    On 5 Feb 2020, at 22:29, Eliot Kimber ekimber@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

    In my XML I can have adjacent elements that should be processed as a unit,
where the adjacent elements all have the same value for a given attribute.
Other elements with the same attribute could be following siblings but
separated by other elements or text nodes, i.e.:

    <p>Text <ph outputclass="x">1</ph><ph outputclass="x">2</ph> more text <ph
outputclass="x">New sequence</ph></p>

    Where the rendered result should combine the first two <ph> elements but
not the third, i.e.:

    <p>Text <x>12</x> more text <x>New sequence</x></p>

    Processing is applied to the first element in the document with the
@outputclass value "x" and then I want to grab any immediately following
siblings with the same @outputclass value and no intervening text or element

    My solution is to use for-each-group like so:

        <xsl:variable name="this" as="element()" select="."/>
        <xsl:variable name="adjacent-sibs" as="element()+">
          <xsl:for-each-group select="($this,
            <xsl:if test=". is $this">
              <xsl:sequence select="current-group()"/>

    Which works, but I'm thinking there must be a more compact way to do the
same selection, but the formulation is escaping me.

    Is there a more compact or more efficient way to make this selection of
only immediately-adjacent following siblings?


    Eliot Kimber

    XSL-List info and archive
    (by email <>)

Current Thread