Re: Concatenate element values based on another key element

Subject: Re: Concatenate element values based on another key element
From: "BC Huang" <bc.huang@xxxxxxxx>
Date: Fri, 13 Oct 2000 07:42:23 -0400
Thank you, Topher.  I have found a way to deal with this kind of situation.
I use key as Topher suggested and the recursive method modified from Michael
Key's example in his book.  Here is the XSLT script.  Tested using Saxon and
it produced the desired output.

Ben
------------------------------------------------
<xsl:stylesheet
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
     version="1.0"
>

<xsl:output method="xml" version="1.0" standalone="no" indent="yes"/>

<xsl:key name="rec-key" match="rec" use="some_id" />

<xsl:template match="test">
  <xsl:element name="test">
    <xsl:for-each select="rec[generate-id(.) =
              generate-id(key('rec-key', some_id)[1])]">

      <rec>
        <some_id><xsl:value-of select="./some_id"/></some_id>
        <xsl:variable name="full-text">
          <xsl:for-each select="key('rec-key', some_id)">
            <xsl:call-template name="merge-text">
              <xsl:with-param name="some-text" select="./some_text"/>
            </xsl:call-template>
          </xsl:for-each>
        </xsl:variable>

        <some_text><xsl:value-of select="$full-text"/></some_text>

      </rec>
    </xsl:for-each>
  </xsl:element>

</xsl:template>

<!-- merge text from multiple elements -->
<xsl:template name="merge-text">
  <xsl:param name="some-text"/>
  <xsl:choose>
    <xsl:when test="$some-text">
      <xsl:variable name="first-line" select="$some-text[1]"/>
      <xsl:variable name="other-lines">
         <xsl:call-template name="merge-text">
           <xsl:with-param name="some-text" select="$some-text[position() !=
1]"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:value-of select="concat($first-line, ' ', $other-lines)"/>
    </xsl:when>
    <xsl:otherwise></xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>



----- Original Message -----
From: Eliot, Topher <Christopher_Eliot@xxxxxxxxxxxxx>
To: <xsl-list@xxxxxxxxxxxxxxxx>
Sent: October 12, 2000 10:35 PM
Subject: RE: Concatenate element values based on another key element


> Here's a partial solution.  It doesn't iterate through the integer values,
> but it does collect
> all the text for each value pretty well.  I gotta go home now, my wife is
> wondering where the
> heck I am.
>
> <?xml version="1.0" encoding="ISO-8859-1" ?>
> <xsl:stylesheet
>   version="1.0"
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
>   <xsl:strip-space elements="*" />
>   <xsl:output method="xml" indent="yes" />
>
>   <!-- Set up a key that finds recs by some_id value -->
>   <xsl:key name="idKey"
>     match="rec"
>     use="some_id" />
>
>   <xsl:template match="/test">
>
>     <!-- Unfortunately I haven't solved the iteration (recursion?)
>          problem here -->
>     <xsl:call-template name="doOneIdValue">
>       <xsl:with-param name="idValue" select="1" />
>     </xsl:call-template>
>
>     <xsl:call-template name="doOneIdValue">
>       <xsl:with-param name="idValue" select="2" />
>     </xsl:call-template>
>
>     <xsl:call-template name="doOneIdValue">
>       <xsl:with-param name="idValue" select="3" />
>     </xsl:call-template>
>   </xsl:template>
>
>   <xsl:template name="doOneIdValue">
>     <xsl:param name="idValue" />
>     <rec>
>       <some_id><xsl:value-of select="$idValue"/></some_id>
>
>       <some_text>
>         <xsl:apply-templates mode="string" select="key('idKey', $idValue)"
> />
>       </some_text>
>
>     </rec>
>   </xsl:template>
>
>   <xsl:template mode="string" match="rec">
>     <xsl:value-of select="some_text" />
>
>   </xsl:template>
>
> </xsl:stylesheet>
>
> > -----Original Message-----
> > From: BC Huang [mailto:bc.huang@xxxxxxxx]
> > Sent: Thursday, October 12, 2000 11:52 AM
> > To: XSL-List@xxxxxxxxxxxxxxxx
> > Subject: Concatenate element values based on another key element
> >
> >
> > I am trying to write a template to concatenate values from an
> > element based
> > on another key element.  The source document looks like this:
> >
> >
> > <test>
> >   <rec>
> >      <some_id>1</some_id>
> >      <some_text>text for id 1</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>2</some_id>
> >      <some_text>first line of text for id 2</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>2</some_id>
> >      <some_text>second line of text for id 2</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>2</some_id>
> >      <some_text>nth line of text for id 2</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>3</some_id>
> >      <some_text>text for id 3</some_text>
> >   </rec>
> > </test>
> >
> > The number of <rec>s can vary and each ID can have as many
> > lines (thus recs)
> > of text.  In terms of the id element, they are duplicates,
> > but I need to
> > concatenate the related the element (some_text) and produce
> > one single rec
> > in the output like this:
> >
> > <test>
> >   <rec>
> >      <some_id>1</some_id>
> >      <some_text>text for id 1</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>2</some_id>
> >      <some_text>first line of text for id 2 second line of
> > text for id 2 nth
> > line of text for id 2</some_text>
> >   </rec>
> >
> >   <rec>
> >      <some_id>3</some_id>
> >      <some_text>text for id 3</some_text>
> >   </rec>
> > </test>
> >
> > Could anyone help me on this.  Thank you very much in advance.
> >
> > Ben
> >
> >
> >
> >  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> >
>
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread