Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - List comparison >Thread Next - RE: List comparison RE: List comparisonTo: NULL Date: 5/9/2006 9:53:00 AM Hi Dmitry, The stylesheet below will compare two lists. Ordering is ignored, and duplicates are allowed and are ignored. I am preparing string hash of two lists, and then comparing the hashes. Also, node-set extension function is being used. Please also note that this solution is not namespace aware. The XSLT processor used is MSXSL 4.0. The XML used is - <lists> <list1> <item name="aaa"/> <item name="bbb"/> </list1> <list2> <item name="aaa"/> <item name="bbb"/> <item name="ccc"/> </list2> </lists> The stylesheet is - <?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0"> <xsl:output method="text" encoding="UTF-8" /> <xsl:key name="dup" match="*" use="." /> <xsl:template match="/lists"> <!-- process 1st list --> <xsl:variable name="l" select="list1" /> <xsl:variable name="x"> <xsl:for-each select="list1/*"> <temp pos="{position()}"> <xsl:value-of select="local-name()" /> <xsl:for-each select="@*"> <xsl:value-of select="local-name()" /> <xsl:value-of select="." /> </xsl:for-each> </temp> </xsl:for-each> </xsl:variable> <xsl:variable name="listA"> <xsl:for-each select="msxsl:node-set($x)/temp[generate-id() = generate-id(key('dup', .)[1])]"> <xsl:sort select="." /> <xsl:variable name="pos" select="@pos" /> <xsl:copy-of select="$l/*[position() = $pos]" /> </xsl:for-each> </xsl:variable> <xsl:variable name="hash1"> <xsl:for-each select="msxsl:node-set($listA)/*"> <xsl:value-of select="local-name()" /> <xsl:for-each select="@*"> <xsl:value-of select="local-name()" /> <xsl:value-of select="." /> </xsl:for-each> </xsl:for-each> </xsl:variable> <!-- process 2nd list --> <xsl:variable name="m" select="list2" /> <xsl:variable name="y"> <xsl:for-each select="list2/*"> <temp pos="{position()}"> <xsl:value-of select="local-name()" /> <xsl:for-each select="@*"> <xsl:value-of select="local-name()" /> <xsl:value-of select="." /> </xsl:for-each> </temp> </xsl:for-each> </xsl:variable> <xsl:variable name="listB"> <xsl:for-each select="msxsl:node-set($y)/temp[generate-id() = generate-id(key('dup', .)[1])]"> <xsl:sort select="." /> <xsl:variable name="pos" select="@pos" /> <xsl:copy-of select="$m/*[position() = $pos]" /> </xsl:for-each> </xsl:variable> <xsl:variable name="hash2"> <xsl:for-each select="msxsl:node-set($listB)/*"> <xsl:value-of select="local-name()" /> <xsl:for-each select="@*"> <xsl:value-of select="local-name()" /> <xsl:value-of select="." /> </xsl:for-each> </xsl:for-each> </xsl:variable> <!-- compare list1 and list2 --> <xsl:choose> <xsl:when test="$hash1 = $hash2"> <xsl:text>NO CHANGES WERE DETECTED</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>CHANGES WERE DETECTED</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> Regards, Mukul "Dmitry Nogin" wrote: > Hi, > > How can I compare two lists? > Ordering should be ignored. > Duplicates are allowed and should be ignored. > > For example: > > <list1> > <item name="aaa"/> > <item name="bbb"/> > </list1> > > <list2> > <item name="aaa"/> > <item name="bbb"/> > <item name="ccc"/> > </list2> > > I'd like to output something like this: > > CHANGES WERE DETECTED > > or > > NO CHANGES WERE DETECTED > > Are there any simple approach? > > > Thanks a lot, > dmitry | ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
