xslt: for-each group, grouping by child nodes?

Discussion in 'XML' started by jon|k, Jan 19, 2006.

  1. jon|k

    jon|k Guest

    hi all--

    i need to do a transformation that removes duplicates (among other
    things). to accomplish that, i'm trying to use for-each-group, but it
    doesn't work. i need to select for duplicates by looking at the child
    node sequence (see sample below). note that when i do an xsl-message on
    the group-by expression inside the for-each-group, it has exactly what
    i'd like to group by listed, but i guess it doesn't like to have a
    sequence of nodes in the group-by? (it repeats way too many times, and
    i'm thinking it's because the expression in the group-by clause is a
    sequence of attribute nodes and not converted to a string or something
    that can be simply "eq"ed?)

    <xsl:for-each-group select="(//sentence|//node)"
    group-by="./child::*/(@cat|@pos)">
    <xsl:apply-templates select="current-group()" />
    </xsl:for-each-group>

    here's sample data. i only want the template run ONCE for each
    combination of sentence/node + the cat/pos attributes of the first
    level children (e.g., only run for the nodes that i've starred
    [although it could be any similar node; as long as it's just run
    once]). note that i don't care what's two levels down, just what's on
    the first level.

    example:
    <sentence id="1" *>
    <node cat="A" *>
    <word pos="E" />
    <word pos="F" />
    </node>
    <node cat="D" * />
    <word pos="B" />
    </sentence>
    <sentence id="2" *>
    <node cat="A" * />
    <node cat="D" />
    </sentence>
    <sentence id="3">
    <node cat="A" />
    <node cat="D" />
    </sentence>

    what am i doing wrong, or have i tried to tackle this completely
    incorrectly? thanks in advance for any help you can give!

    jon
     
    jon|k, Jan 19, 2006
    #1
    1. Advertising

  2. jon|k

    jon|k Guest

    oops--contrary to my typo in the title, i'm using for-each-group, not
    grouping by for-each :)

    jon

    jon|k wrote:
    > hi all--
    >
    > i need to do a transformation that removes duplicates (among other
    > things). to accomplish that, i'm trying to use for-each-group, but it
    > doesn't work. i need to select for duplicates by looking at the child
    > node sequence (see sample below). note that when i do an xsl-message on
    > the group-by expression inside the for-each-group, it has exactly what
    > i'd like to group by listed, but i guess it doesn't like to have a
    > sequence of nodes in the group-by? (it repeats way too many times, and
    > i'm thinking it's because the expression in the group-by clause is a
    > sequence of attribute nodes and not converted to a string or something
    > that can be simply "eq"ed?)
    >
    > <xsl:for-each-group select="(//sentence|//node)"
    > group-by="./child::*/(@cat|@pos)">
    > <xsl:apply-templates select="current-group()" />
    > </xsl:for-each-group>
    >
    > here's sample data. i only want the template run ONCE for each
    > combination of sentence/node + the cat/pos attributes of the first
    > level children (e.g., only run for the nodes that i've starred
    > [although it could be any similar node; as long as it's just run
    > once]). note that i don't care what's two levels down, just what's on
    > the first level.
    >
    > example:
    > <sentence id="1" *>
    > <node cat="A" *>
    > <word pos="E" />
    > <word pos="F" />
    > </node>
    > <node cat="D" * />
    > <word pos="B" />
    > </sentence>
    > <sentence id="2" *>
    > <node cat="A" * />
    > <node cat="D" />
    > </sentence>
    > <sentence id="3">
    > <node cat="A" />
    > <node cat="D" />
    > </sentence>
    >
    > what am i doing wrong, or have i tried to tackle this completely
    > incorrectly? thanks in advance for any help you can give!
    >
    > jon
     
    jon|k, Jan 19, 2006
    #2
    1. Advertising

  3. jon|k

    jon|k Guest

    ok, in case anyone else is wondering, i've solved the problem by adding
    [1] to the select attribute of apply-templates. i think that gives me
    the results i want.

    <xsl:for-each-group select="(//sentence|//node)"
    group-by="./child::*/(@cat|@pos)">
    <xsl:apply-templates select="current-group()[1]" />
    </xsl:for-each-group>

    jon

    jon|k wrote:
    > hi all--
    >
    > i need to do a transformation that removes duplicates (among other
    > things). to accomplish that, i'm trying to use for-each-group, but it
    > doesn't work. i need to select for duplicates by looking at the child
    > node sequence (see sample below). note that when i do an xsl-message on
    > the group-by expression inside the for-each-group, it has exactly what
    > i'd like to group by listed, but i guess it doesn't like to have a
    > sequence of nodes in the group-by? (it repeats way too many times, and
    > i'm thinking it's because the expression in the group-by clause is a
    > sequence of attribute nodes and not converted to a string or something
    > that can be simply "eq"ed?)
    >
    > <xsl:for-each-group select="(//sentence|//node)"
    > group-by="./child::*/(@cat|@pos)">
    > <xsl:apply-templates select="current-group()" />
    > </xsl:for-each-group>
    >
    > here's sample data. i only want the template run ONCE for each
    > combination of sentence/node + the cat/pos attributes of the first
    > level children (e.g., only run for the nodes that i've starred
    > [although it could be any similar node; as long as it's just run
    > once]). note that i don't care what's two levels down, just what's on
    > the first level.
    >
    > example:
    > <sentence id="1" *>
    > <node cat="A" *>
    > <word pos="E" />
    > <word pos="F" />
    > </node>
    > <node cat="D" * />
    > <word pos="B" />
    > </sentence>
    > <sentence id="2" *>
    > <node cat="A" * />
    > <node cat="D" />
    > </sentence>
    > <sentence id="3">
    > <node cat="A" />
    > <node cat="D" />
    > </sentence>
    >
    > what am i doing wrong, or have i tried to tackle this completely
    > incorrectly? thanks in advance for any help you can give!
    >
    > jon
     
    jon|k, Jan 20, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    21,033
    Martin Honnen
    Oct 4, 2005
  2. Replies:
    1
    Views:
    580
    Soren Kuula
    Aug 24, 2006
  3. Replies:
    1
    Views:
    1,208
    Joe Kesselman
    Nov 1, 2006
  4. tuka
    Replies:
    3
    Views:
    692
    Joe Kesselman
    Jun 22, 2007
  5. MRe
    Replies:
    4
    Views:
    791
    Dimitre Novatchev
    Aug 16, 2008
Loading...

Share This Page