ant284_prg Posted July 9, 2009 Share Posted July 9, 2009 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 More sharing options...
aalbetski Posted July 9, 2009 Share Posted July 9, 2009 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> Link to comment Share on other sites More sharing options...
ant284_prg Posted July 10, 2009 Author Share Posted July 10, 2009 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 More sharing options...
aalbetski Posted July 10, 2009 Share Posted July 10, 2009 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 More sharing options...
ant284_prg Posted July 10, 2009 Author Share Posted July 10, 2009 Thank you sooooo much, It works!!!! I tried before the following-sibling but didn't work maybe because I used it in the <xsl:variable ../> I have been working this non-stop since tuesday now it worksI'm very grateful!Anthony Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.