This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Can't Obtain Results


> Here's my the situation:
>
> I have an XML or tree the looks like this:
>
>  #root>
>    #keyset>
>      #f1>some text#/f1>
>      #f2>some text#/f2>
>      #f3>some text#/f3>
>      #f6>some text#/f6>
>    #/keyset>
>    #keyset outlet="cb">
>      #f2>SOMETEXT#/f2>
>      #f3>SOMETEXT#/f3>
>      #f4>SOMETEXT#/f4>
>      #f5>SOMETEXT#/f5>
>   #/keyset>
> #/root>
>
>
> I am passing in a parameter called outlet
>
> If the outlet parameter is "cb" - after transformation I want
> it to look like this:
>
>  #root>
>    #keyset>
>      #f1>some text#/f1>
>      #f2>SOMETEXT#/f2>
>      #f3>SOMETEXT#/f3>
>      #f4> SOMETEXT#/f4>
>      #f5> SOMETEXT#/f5>
>      #f6>some text#/f6>
>    #/keyset>
>  #/root>

What's special about f1 and f6? Is it that they are the first and last
elements in the first keyset, or is it that they are the only ones not
present in the second keyset? (Sometimes reverse engineering the algorithm
from an example of its output isn't easy...)

Let's assume the latter. In this case you have an elimination-of-duplicates
problem, which is essentially the same as a grouping problem. The grouping
key (the thing that's the same between matching elements) is the element
name rather than it's value, so you can't use the simple
*[not(.=preceding::*)] technique; instead you need to use keys.

Look up Muenchian grouping in your favourite textbook or at
www.jenitennison.com/xslt/grouping, and use it with a grouping key declared
as

<xsl:key name="g" match="keyset/*" use="name()"/>

Or if you want to use XSLT 2.0, as implemented in Saxon 7.1, you can write

<xsl:for-each-group select="(keyset[1] | keyset[@outlet=$outlet])/*"
 group-by = "name()">
   <xsl:copy-of select="."/>
</xsl:for-each-group>

Michael Kay
Software AG
home: Michael.H.Kay@ntlworld.com
work: Michael.Kay@softwareag.com

>
> If the outlet parameter is "default" - after transformation I
> want it to look like this:
>
>  #root >
>    #keyset >
>      #f1>some text#/f1>
>      #f2>some text#/f2>
>      #f3>some text#/f3>
>      #f6>some text#/f6>
>    #/keyset>
>  #/root>
>
> I have tried several different approches with for-each
> statements etc, but have been unable to achieve my results.
> This is my
>
> most recent attempt and I get close, but I can't figure out
> how to determine if I have already found a match.
>
>  #xsl:template match="/">
>    #xsl:param name="outlet">cb#/xsl:param>
>    #xsl:variable name="k1" select="/root/keyset[@outlet=$outlet]/*"/>
>    #xsl:for-each select="/root/keyset[@outlet='default']/*">
>      #xsl:variable name="dflt" select="."/>
>      #xsl:for-each select="$k1">
>        #xsl:choose>
>          #xsl:when test="name($dflt)= name(.)">
>            #xsl:copy-of select="."/>
>          #/xsl:when>
>          #xsl:when test="not(name(@dflt)=name(.)) and
> position()=last()">
>           #xsl:copy-of select="$dflt"/>
>          #/xsl:when>
>        #/xsl:choose>
>      #/xsl:for-each>
>    #/xsl:for-each>
>  #/xsl:template>
>
>
> Thanks
>
> Lindy
>
>
> ------------------------------------------------
> Visit iWon.com - the Internet's largest guaranteed cash giveaway!
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]