2013-05-07 4 views
1

J'ai un cas où il y a 2 variables XML de la même structure. Je veux faire la différence entre les deux.XSLT - Différence entre 2 variables XML

Disons que V1 (représente les nouveaux enregistrements) comporte des éléments a1, a2, a3, a4 et V2 (REPRÉSENTE Les enregistrements existants) comporte des éléments a5, a7, a3

Ici, variable a3 qui est là en V1 est en vigueur dans la version 2, donc je veux me débarrasser de celui-là et je veux une nouvelle variable qui ne détient que {a1, a2, a4}

Voici mes 2 variables XML

Première:

<ReadUsersResponse> 
    <User> 
     <EmailAddress>aaa</EmailAddress> 
     <Name>a</Name> 
     <ObjectId>101</ObjectId> 
    </User> 
    <User> 
     <EmailAddress>bbb</EmailAddress> 
     <Name>b</Name> 
     <ObjectId>103</ObjectId> 
    </User> 
    <User> 
     <EmailAddress>ccc</EmailAddress> 
     <Name>c</Name> 
     <ObjectId>104</ObjectId> 
    </User> 
</ReadUsersResponse> 

Deuxième:

<ReadUsersResponse> 
    <User> 
     <EmailAddress>ddd</EmailAddress> 
     <Name>d</Name> 
     <ObjectId>104</ObjectId> 
    </User> 
    <User> 
     <EmailAddress>bbb</EmailAddress> 
     <Name>b</Name> 
     <ObjectId>103</ObjectId> 
    </User> 
    <User> 
     <EmailAddress>ccc</EmailAddress> 
     <Name>c</Name> 
     <ObjectId>107</ObjectId> 
    </User> 
</ReadUsersResponse> 

Comparez ObjectId de chaque Et voici ce que je veux: (Trim ObjectId 103 comme il est déjà disponible dans Variable2)

<ReadUsersResponse> 
    <User> 
     <EmailAddress>aaa</EmailAddress> 
     <Name>a</Name> 
     <ObjectId>101</ObjectId> 
    </User> 
    <User> 
     <EmailAddress>ccc</EmailAddress> 
     <Name>c</Name> 
     <ObjectId>104</ObjectId> 
    </User> 
</ReadUsersResponse> 

J'ai essayé mais je peux » t le fais.

L'approche que je suivais est d'abord fusionner ces 2 variables XML en 1 variable dans 2 étiquettes séparées Ex ..first Var ... ..second Var ...

J'ai des problèmes avec ceci et je ne peux pas le comprendre. Est-ce la bonne approche? Ou y a-t-il une alternative? Est-ce que quelqu'un sait d'une solution.

Merci à l'avance

Cordialement

Répondre

0

Essayez quelque chose comme ceci:

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

    <xsl:key name="kuser" match="User" 
      use="concat(ObjectId,'#', EmailAddress, '#', Name)" /> 
    <xsl:variable name="u2" select="document('doc_2.xml')"/> 

    <xsl:template match="User"> 
     <xsl:variable name="user_found"> 
      <xsl:apply-templates select="$u2/ReadUsersResponse" mode="checkuser" > 
       <xsl:with-param name="user" select="." /> 
      </xsl:apply-templates> 
     </xsl:variable> 
     <xsl:if test="$user_found != 'true'"> 
      <xsl:copy> 
       <xsl:apply-templates /> 
      </xsl:copy> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="ReadUsersResponse" mode="checkuser"> 
     <xsl:param name="user"/> 
     <xsl:if test="key('kuser', concat($user/ObjectId,'#', $user/EmailAddress, '#', $user/Name))" > 
      <xsl:text>true</xsl:text> 
    </xsl:if> 
    </xsl:template> 
    <xsl:template match="node() | @*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node() " /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

qui va générer la sortie suivante:

<ReadUsersResponse> 
     <User> 
       <EmailAddress>aaa</EmailAddress> 
       <Name>a</Name> 
       <ObjectId>101</ObjectId> 
     </User> 

     <User> 
       <EmailAddress>ccc</EmailAddress> 
       <Name>c</Name> 
       <ObjectId>104</ObjectId> 
     </User> 
</ReadUsersResponse> 

Ils valeur de clé use="concat(ObjectId,'#', EmailAddress, '#', Name)" pourraient être adaptés en fonction sur quelle partie de l'utilisateur devrait-il cked.

Pour quelques explications ont: par exemple Lookup table in a separate document
Un point essentiel est qu'un indice distinct est préparé pour chaque document source qui est chargé (en utilisant la fonction document()).

0

Une autre solution est:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:param name="first"> 
    <ReadUsersResponse> 
     <User> 
     <EmailAddress>aaa</EmailAddress> 
     <Name>a</Name> 
     <ObjectId>101</ObjectId> 
     </User> 
     <User> 
     <EmailAddress>bbb</EmailAddress> 
     <Name>b</Name> 
     <ObjectId>103</ObjectId> 
     </User> 
     <User> 
     <EmailAddress>ccc</EmailAddress> 
     <Name>c</Name> 
     <ObjectId>104</ObjectId> 
     </User> 
    </ReadUsersResponse> 
    </xsl:param> 
    <xsl:param name="second"> 
    <ReadUsersResponse> 
     <User> 
     <EmailAddress>ddd</EmailAddress> 
     <Name>d</Name> 
     <ObjectId>104</ObjectId> 
     </User> 
     <User> 
     <EmailAddress>bbb</EmailAddress> 
     <Name>b</Name> 
     <ObjectId>103</ObjectId> 
     </User> 
     <User> 
     <EmailAddress>ccc</EmailAddress> 
     <Name>c</Name> 
     <ObjectId>107</ObjectId> 
     </User> 
    </ReadUsersResponse> 
    </xsl:param> 

    <xsl:key name="User" match="User" use="ObjectId"/> 
    <xsl:template match="/"> 
    <xsl:for-each select="$first//User"> 
     <xsl:variable name="ObjectId" select="ObjectId"/> 
     <xsl:variable name="User"> 
     <xsl:copy-of select="."/> 
     </xsl:variable> 
     <xsl:message> 
     <xsl:copy-of select="$User"/> 
     </xsl:message> 
     <xsl:choose> 
     <xsl:when 
      test="$ObjectId = $second//User/ObjectId[preceding-sibling::EmailAddress = $User/User/EmailAddress]"/> 
     <xsl:otherwise> 
      <xsl:copy> 
      <xsl:copy-of select="."/> 
      </xsl:copy> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet>