Re: [xsl] Muenchian grouping: help with 'use' and multiple elements

Subject: Re: [xsl] Muenchian grouping: help with 'use' and multiple elements
From: Mukul Gandhi <mukul_gandhi@xxxxxxxxx>
Date: Fri, 9 Jul 2004 23:33:28 -0700 (PDT)
Hi Justin,
  Please try the XSL -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xalan="http://xml.apache.org/xalan";>

<xsl:output method="xml" version="1.0"
encoding="UTF-8" indent="yes"/>
		
<xsl:key name="by-restr" match="r_ele" use="restr" />
	
<xsl:template match="/entry">
  <entry>
    <xsl:variable name="rtf">
      <xsl:for-each select="r_ele">
	<r_ele>
	  <reb>
	    <xsl:value-of select="reb"/>
	  </reb>
	  <restr>
	    <xsl:for-each select="re_restr">
	      <xsl:sort select="."/>
	      <xsl:value-of select="."/>
	      <xsl:if test="position() != last()">
		<xsl:text>,</xsl:text>
	      </xsl:if>
	    </xsl:for-each>
	  </restr>
	</r_ele>
      </xsl:for-each>
    </xsl:variable>
			
    <xsl:for-each select="xalan:nodeset($rtf)/r_ele">
      <xsl:if test="generate-id(.) =
generate-id(key('by-restr', restr)[1])">
       <group>
        <rebs>
         <xsl:for-each select="key('by-restr',
restr)">
            <reb>			              	      <xsl:value-of
select="reb" />
	    </reb>
         </xsl:for-each>
	</rebs>
	<re_restrs>
	  <xsl:if test="restr != '' ">
            <xsl:call-template name="tokenise-restr">
              <xsl:with-param name="str"
select="restr" />                                     
              <xsl:with-param name="delim"
select="','" />                                       

            </xsl:call-template>
          </xsl:if>
        </re_restrs>			         
       </group>
     </xsl:if>
   </xsl:for-each>
</entry>

</xsl:template>

<xsl:template name="tokenise-restr">
   <xsl:param name="str" />
   <xsl:param name="delim" />
          
   <xsl:if test="not(contains($str, $delim))">
     <re_restr>
       <xsl:value-of select="$str" />
     </re_restr>    
   </xsl:if>          
   <xsl:if test="substring-after($str, $delim) != ''
">             
     <re_restr>
       <xsl:value-of select="substring-before($str,
$delim)" />
     </re_restr>
     <xsl:call-template name="tokenise-restr">
        <xsl:with-param name="str"
select="substring-after($str, $delim)" />
        <xsl:with-param name="delim" select="$delim"
/>
     </xsl:call-template>
   </xsl:if>
</xsl:template>
      
</xsl:stylesheet>

Regards,
Mukul

--- Justin Anderson <justin_anderson@xxxxxxx> wrote:
> I'll start this off by mentioning that I started to
> learning XSLT a  
> week ago, so please don't be too harsh with me if
> the answer to this  
> question is obvious.
> 
> A description of the source and the desired output
> in plain english:
> 
> The xml file I'm using is an Asian dictionary in
> which different  
> pronounciations (reb) are limited to specific
> characters (re_restr).  
> Sometimes certain pronounciations have the same set
> of restrictions. In  
> those cases, I'd like to group them together. I made
> a dummy entry  
> below based on numbers. 12 and 21 both contain 'one'
> and 'two', so they  
> should be grouped together. That's what I'm trying
> to do.
> 
> I'm trying to do single-level Muenchian grouping of
> r_ele elements by  
> their re_restr children, of which there can be 0 to
> infinity instances  
> in any order. I'm not sure if Muenchian grouping
> works when the 'use'  
> element doesn't exist all the time, and I have no
> clue how to make the  
> 'use' element consider all of the re_restr children
> in an r_ele at the  
> same time.
> 
> I've included a sample of the xml source file, the
> xsl file (which I'm  
> pretty sure isn't anything like I need it to be),
> the desired xml  
> output, and the actual xml output.
> 
> Thanks in advance for any light shed on this,
> Justin Anderson
> 
> 
> XML source file:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <entry>
> 	<k_ele>
> 		<keb>one</keb>
> 	</k_ele>
> 	<k_ele>
> 		<keb>two</keb>
> 	</k_ele>
> 	<k_ele>
> 		<keb>three</keb>
> 	</k_ele>
> 	<r_ele>
> 		<reb>12</reb>
> 		<re_restr>one</re_restr>
> 		<re_restr>two</re_restr>
> 	</r_ele>
> 	<r_ele>
> 		<reb>32</reb>
> 		<re_restr>two</re_restr>
> 		<re_restr>three</re_restr>
> 	</r_ele>
> 	<r_ele>
> 		<reb>21</reb>
> 		<re_restr>two</re_restr>
> 		<re_restr>one</re_restr>
> 	</r_ele>
> </entry>
> 
> XSL file:
> 
> <?xml version='1.0' encoding='utf-8' ?>
> <xsl:stylesheet
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";   
> version="1.0">
> 	<xsl:output method="xml"/>
> 	
> 	<xsl:key name="r_ele-by-re_restr" match="r_ele"
> use="re_restr"/>
> 	
> 	<xsl:template match="/">
> 		<xsl:apply-templates/>
> 	</xsl:template>
> 	
> 	<xsl:template match="entry">
> 		<entry>
> 		<xsl:for-each  
>
select="r_ele[generate-id(.)=generate-id(key('r_ele-by-
> 
> re_restr',re_restr))]">
> 		<xsl:sort select="reb" order="ascending"/>
> 			<group>
> 			<xsl:for-each
> select="key('r_ele-by-re_restr',re_restr)">
> 			<xsl:sort select="reb"/> 				
> 					<rebs>
> 						<reb>
> 							<xsl:value-of select="reb"/>
> 						</reb>
> 					</rebs>
> 					<re_restrs>
> 						<xsl:for-each select="re_restr">
> 						<xsl:sort select="." order="ascending" />
> 							<re_restr>
> 								<xsl:value-of select="."/>
> 							</re_restr>
> 						</xsl:for-each>
> 					</re_restrs>
> 			</xsl:for-each>
> 			</group>
> 		</xsl:for-each>
> 		</entry>	
> 	</xsl:template>
> 
> </xsl:stylesheet>
> 
> 
> Desired results:
> 
> <entry>
> 	<group>
> 		<rebs>
> 			<reb>12</reb>
> 			<reb>21</reb>
> 		</rebs>
> 		<re_restrs>
> 			<re_restr>one</re_restr>
> 			<re_restr>two</re_restr>
> 		</re_restrs>
> 	</group>
> 	<group>
> 		<rebs>
> 			<reb>32</reb>
> 		</rebs>
> 		<re_restrs>
> 			<re_restr>two</re_restr>
> 			<re_restr>three</re_restr>
> 		</re_restrs>
> 	</group>
> </entry>
> 
> Current actual results:
> 
> <entry>
> 	<group>
> 		<rebs>
> 			<reb>12</reb>
> 		</rebs>
> 		<re_restrs>
> 			<re_restr>one</re_restr>
> 			<re_restr>two</re_restr>
> 		</re_restrs>
> 	</group>
> 	<group>
> 		<rebs>
> 			<reb>21</reb>
> 		</rebs>
> 		<re_restrs>
> 			<re_restr>one</re_restr>
> 			<re_restr>two</re_restr>
> 		</re_restrs>
> 	</group>
> 	<group>
> 		<rebs>
> 			<reb>32</reb>
> 		</rebs>
> 		<re_restrs>
> 			<re_restr>two</re_restr>
> 			<re_restr>three</re_restr>
> 		</re_restrs>
> 	</group>
> </entry>



		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

Current Thread