Jump to content

Xslt Looping Problem


Recommended Posts

Hi I have a problem currently with looping in XSLT.. What i'm trying to do is removing duplicates from a Node structure I have many regs that contain a set of persons. when i do <xsl:for-each select="./persons/person"> <xsl:if test="./name[.=following::name]">true</xsl:if></xsl:for-each>when it reaches the first Ant. it will print true instead Nothing because it sees in the next person's set another Ant but I want it to print nothing!while for Bob because there no more bob afterwards it won't print anything which is good..I could not find the solution any help is appreciated....XML BELOW and below the xml is my XSLT<roots> <regs> <persons> <person> <name>Ant</name> <type></type> </person> <person> <name>Bob</name> <type></type> </person> </persons> </regs> <regs> <persons> <person> <name>Ant</name> <type></type> </person> <person> <name>Mark</name> <type></type> </person> </persons> </regs><roots>part of my XSLT<xsl:for-each select = "regs"> <xsl:for-each select="Persons/Person"> <xsl:if test="./name[.=following::name]">true</xsl:if> </xsl:for-each></xsl:for-each

Link to comment
Share on other sites

I'm not really sure I understand your desired output. If you are trying to print a list without duplicates, the Muenchian method works fine here. (Google Muenchian for an explanation of how it works or search this forum, its been answered before)If I've misunderstood your problem, please enlighten me by showing what your desired output should look like, the following will produce this: AntBobMark

	<xml id="xslStyle">		<xsl:stylesheet			xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			xmlns:msxsl="urn:schemas-microsoft-com:xslt"			version="1.0">		<xsl:key name="PName" match="person" use="name"/>		<xsl:output method="html" />		<xsl:template match="/">				<xsl:for-each select="//person[count(. | key('PName',name)[1]) = 1]">					<xsl:sort select="name" order="ascending" />					<xsl:value-of select="name"/>				</xsl:for-each>			</xsl:template>		</xsl:stylesheet>	</xml>

Edited by aalbetski
Link to comment
Share on other sites

Thank you very much... does not fully work but works better!!The problem is thathere again is my xml sorry I'm not following the name of previous xml

<roots>	  <root>			<persons>				  <person>						  <name>Anthony</name>						 <type>a</type>				   </person>				  <person>						  <name>Eric</name>						 <type>b</type>				   </person>				  <person>						  <name>Anthony</name>						 <type>c</type>				   </person>				  <person>						  <name>Eric</name>						 <type>d</type>				   </person>			 </persons>	  </root>	 <root>			<persons>				  <person>						  <name>Anthony</name>						 <type>a</type>				   </person>				  <person>						  <name>Marc</name>						 <type>b</type>				   </person>				  <person>						  <name>Anthony</name>						 <type>e</type>				   </person>				  <person>						  <name>Marc</name>						 <type>d</type>				   </person>			 </persons>	  </root></roots>

and instead of getting the result I would like

	 first root has people		<peoples>			   <people> 					   <name>Anthony</name>						</types>							  <type>a</type>							  </type>b</type>						 </types>			  </people>			   <people> 					   <name>Eric</name>						</types>							  <type>c</type>							  </type>d</type>						 </types>			  </people>	   </peoples>second Root  has		<peoples>			   <people> 					   <name>Anthony</name>						</types>							  <type>a</type>							  </type>e</type>						 </types>			  </people>			   <people> 					   <name>Marc</name>						</types>							  <type>b</type>							  </type>d</type>						 </types>			  </people>	   </peoples>

I get this results

	 root 1 has these people		<peoples>			   <people> 					   <name>Anthony</name>						</types>							  <type>a</type>							  </type>b</type>						 </types>			  </people>			   <people> 					   <name>Eric</name>						</types>							  <type>c</type>							  </type>d</type>						 </types>			  </people>	   </peoples> root 2 has these people		<peoples>				 <people> 					   <name>Marc</name>						</types>							  <type>b</type>							  </type>d</type>						 </types>			  </people>	   </peoples>

You can see that I'm trying to group the name together(doesn't need to be sorted) into 1 tag, and put under each name there type(can be random).also the problem as you can see on the second root Anthony Has been removed...... the xslt is this

//START....<xsl:key name="PName" match=" persons/person" use="name"/>	<xsl:template match="/">		<xsl:for-each select="ADDITIONAL_PATH_NOT_SHOWN/root/roots">									 <xsl:variable name="root_pos" select="position()"/>									root <xsl:value-of select="position()"/> has these people										   <xsl:variable name="unique-list" select="person[count(. | key('PName',name)[$root_pos]) = 1]"/>											<xsl:variable name="list" select="person[.|key('PName',name)[1]]"/>											 <peoples>													 <xsl:for-each select="$unique-list">												  															<people>																	  <xsl:value-of select="name"/>																	   <types>																	   <xsl:for-each select="$list">																				 <type>																					  <xsl:value-of select="../type">																				 </type>																	  </xsl:for-each															 </people>													 </xsl:for-each>											 </peoples>					 							  </xsl:for-each>				  </template>

I just don't see where I'm going wrong but thank you for help it help a lot... I just hope that the compare functionality would only work for a set of nodes and not the entire XMLAnthony

Link to comment
Share on other sites

The grouping technique will not work with this problem. The key will index the entire tree so it will eliminates items that you would to appear in your second root grouping, try this instead (again, I am only giving you the framework to get the data you want, its up to you to fill in the blanks)

				<xsl:for-each select="//root">					<xsl:for-each select="persons/person">						<xsl:if test="not(following-sibling::*/name = name)">							<xsl:value-of select="name"/>						</xsl:if>					</xsl:for-each>				</xsl:for-each>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...