Re: [xsl] How to compare the attributes of two elements to ensure that they are equal

Subject: Re: [xsl] How to compare the attributes of two elements to ensure that they are equal
From: Mukul Gandhi <mukulgw3@xxxxxxxxx>
Date: Wed, 29 Oct 2003 07:35:03 -0800 (PST)
Hi Arvind,

Sorry, I discovered some bugs in my previous answer. I
believe the following XSL is correct --

<?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";
extension-element-prefixes="xalan">
<xsl:output method="xml" version="1.0"
encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
  <xsl:variable name="temp-rtf">
    <xsl:for-each select="*">
      <xsl:if test="name(.)= 'a' ">
	<a>
	  <xsl:for-each select="@*">
	    <att>
	      <name>
		 <xsl:value-of select="name(.)"/>
	      </name>
	      <value>
	        <xsl:value-of select="."/>
	      </value>
	    </att>
	  </xsl:for-each>
	</a>
     </xsl:if>
     <xsl:if test="name(.)= 'c' ">
        <c>
	  <xsl:for-each select="@*">
	    <att>
	      <name>
		 <xsl:value-of select="name(.)"/>
	      </name>
	      <value>
	         <xsl:value-of select="."/>
	      </value>
	    </att>
	  </xsl:for-each>
	</c>
     </xsl:if>
  </xsl:for-each>
</xsl:variable>
		
<xsl:variable name="a-attributes"
select="xalan:nodeset($temp-rtf)/a//att"/>
<xsl:variable name="c-attributes"
select="xalan:nodeset($temp-rtf)/c//att"/>

<xsl:variable name="result">

<xsl:for-each
select="xalan:nodeset($temp-rtf)/a//att">
   <xsl:for-each
select="xalan:nodeset($temp-rtf)/c//att">
     <xsl:if test="./name =
$a-attributes[position()]/name">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'y' "/>
	</xsl:call-template>
     </xsl:if>
     <xsl:if test="./value =
$a-attributes[position()]/value">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'y' "/>
	</xsl:call-template>
     </xsl:if>
     <xsl:if test="not(./name =
$a-attributes[position()]/name)">
        <xsl:call-template name="calculateResult">
	    <xsl:with-param name="x" select=" 'n' "/>
	</xsl:call-template>
     </xsl:if>
     <xsl:if test="not(./value =
$a-attributes[position()]/value)">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'n' "/>
	</xsl:call-template>
     </xsl:if>
  </xsl:for-each>
</xsl:for-each>
			
<xsl:for-each
select="xalan:nodeset($temp-rtf)/c//att">
  <xsl:for-each
select="xalan:nodeset($temp-rtf)/a//att">
     <xsl:if test="./name =
$c-attributes[position()]/name">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'y' "/>
	</xsl:call-template>
     </xsl:if>
     <xsl:if test="./value =
$c-attributes[position()]/value">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'y' "/>
        </xsl:call-template>
     </xsl:if>
     <xsl:if test="not(./name =
$c-attributes[position()]/name)">
        <xsl:call-template name="calculateResult">
	   <xsl:with-param name="x" select=" 'n' "/>
	</xsl:call-template>
     </xsl:if>
     <xsl:if test="not(./value =
$c-attributes[position()]/value)">
	<xsl:call-template name="calculateResult">
	    <xsl:with-param name="x" select=" 'n' "/>
	</xsl:call-template>
     </xsl:if>
  </xsl:for-each>
</xsl:for-each>

</xsl:variable>
		
<xsl:if test="xalan:nodeset($result)/r2[1] =
'notequal' ">
   Attribute sets not equal
</xsl:if>

<xsl:if test=" not(xalan:nodeset($result)/r2[1] =
'notequal' )">
   <xsl:if test="xalan:nodeset($result)/r1[1] =
'equal' ">
      Attribute sets equal
   </xsl:if>
</xsl:if>
</xsl:template>

<xsl:template name="calculateResult">
   <xsl:param name="x"/>
     <xsl:if test="$x = 'y' ">
       <r1>equal</r1>
     </xsl:if>
     <xsl:if test="$x = 'n' ">
       <r2>notequal</r2>
     </xsl:if>
</xsl:template>
	
</xsl:stylesheet>

I believe Dimitre's answer ;-is also correct-;

Regards,
Mukul


> --- Arvind Bassi <arvind_bassi@xxxxxxxxxxx> wrote:
> > What is the best way to compare two elements in
> > terms of their
> > attributes, and the attribute values? I need to
> > ensure that each
> > element has the same number of attributes, the
> same
> > attribute names and
> > the same attribute values.
> > 
> > I am currently working on a stylesheet which
> > compares two xml
> > documents, and generates the differences between
> > them. I have used Lar
> > Huttar's xml document comparison stylesheet as my
> > base (located at
> > http://www.dpawson.co.uk), but am stuck on
> > augmenting it with checks on
> > attributes.
> > 
> > I am currently stuck with something along the
> lines
> > of:
> > 
> >    ...
> >        <xsl:call-template
> name="compare-attributes">
> >           with nodes as parameters
> >    ...
> >    <xsl:template name="compare-attributes">
> >         <xsl:param name="attrA"/>
> >         <xsl:param name="attrB"/>
> >         <xsl:for-each select="$attrA/@*">
> >                .... check that the same attribute
> > exists with
> >                .... the same attribute exists 
> >                if it does then compare the values
> > for equality
> > 
> >         </xsl:for-each>
> >     </xsl:template>
> > 
> 
=== message truncated ===


__________________________________
Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

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


Current Thread