Re: [xsl] Conditional merge of 2 XML files

Subject: Re: [xsl] Conditional merge of 2 XML files
From: Thomas Tarpin-Lyonnet <bartleby@xxxxxxxxxx>
Date: Mon, 05 Sep 2005 23:48:06 +0800
Hello,

The solution that Joris gave me was working perfectly but
unfortunately, we have
changed a bit the structure of the xml and now there are some cases where
it's
not working.
Here is the new structure of the files:
file_1.xml has changed to be:
<?xml version="1.0"?>
<testCampaignResults>
 <header>
   <headerTitle>XCRD Test Campaign Configuration</headerTitle>
   <date>25/08/2005</date>
   <cardConfig>
     <xlsCardNum>0000000023456789</xlsCardNum>
     <efCardSize>32</efCardSize>
     <samKeyInfo>003F</samKeyInfo>
     <efIssuerSize>4C</efIssuerSize>
     <efLoyaltySize>03C8</efLoyaltySize>
     <efCpnSize>0198</efCpnSize>
   </cardConfig>
   <versions>
     <driver>Java V2 card     V1.01</driver>
     <campaign> TEST_CAMPAIGN v1.15</campaign>
     <samDriver>Software SAM</samDriver>
     <modules>
       <xcrd>Xcrd Core        V1.27</xcrd>
       <xdem> XDEM core v1.1 </xdem>
       <xsws> XSWS HCK v2.5  </xsws>
       <xct> XCT  Core V1.1 </xct>
       <xfat> XFAT core v2.0 </xfat>
       <xdat> XDAT core v1.0 </xdat>
     </modules>
   </versions>
   <timeElapsed>20875</timeElapsed>
 </header>
 <xcrdApi>
   <xcrdApiTitle>XCRD APIs Testing Results</xcrdApiTitle>
   <api>
     <apiName result="KO" timeElapsed="20875">GetVer</apiName>
     <testFamily>
       <familyName result="OK" timeElapsed="4015">GetVer_Nom</familyName>
       <testNum>
         <num result="OK" timeElapsed="4015">GetVer_Nom_T1</num>
         <case>
           <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C1</caseName>
         </case>
         <case>
           <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C3</caseName>
         </case>
       </testNum>
     </testFamily>
     <testFamily>
       <familyName result="KO" timeElapsed="17672">GetVer_Str</familyName>
       <testNum>
         <num result="KO" timeElapsed="17672">GetVer_Str_T1</num>
         <case>
           <caseName result="KO"
timeElapsed="00:00:02">GetVer_Str_T1_C1</caseName>
           <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_OpenCardSession</apiCall>
           <apiCall result="KO" eCode="XCRD_NO_ERROR"
rCode="XCRD_POWER_FAILED">XCRD_OpenSamSession</apiCall>
           <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_CloseCardSession</apiCall>
         </case>
       </testNum>
     </testFamily>
   </api>
 </xcrdApi>
</testCampaignResults>

and file_2.xml will be:
<?xml version="1.0"?>
<testCampaignResults>
 <xcrdApi>
   <xcrdApiTitle>XCRD APIs Testing Results</xcrdApiTitle>
   <api>
     <apiName>GetVer</apiName>
     <testFamily>
       <familyName>GetVer_Nom</familyName>
       <testNum>
         <num>GetVer_Nom_T1</num>
         <case>
           <caseName>GetVer_Nom_T1_C1</caseName>
         </case>
         <case>
           <caseName>GetVer_Nom_T1_C2</caseName>
         </case>
         <case>
           <caseName>GetVer_Nom_T1_C3</caseName>
         </case>
       </testNum>
     </testFamily>
     <testFamily>
       <familyName>GetVer_Fmt</familyName>
       <testNum>
         <num>GetVer_Fmt_T1</num>
         <case>
           <caseName>GetVer_Fmt_T1_C1</caseName>
         </case>
         <case>
           <caseName>GetVer_Fmt_T1_C2</caseName>
         </case>
       </testNum>
     </testFamily>
     <testFamily>
       <familyName>GetVer_Str</familyName>
       <testNum>
         <num>GetVer_Str_T1</num>
         <case>
           <caseName>GetVer_Str_T1_C1</caseName>
         </case>
         <case>
           <caseName>GetVer_Str_T1_C2</caseName>
         </case>
         <case>
           <caseName>GetVer_Str_T1_C31</caseName>
         </case>
       </testNum>
     </testFamily>
   </api>
 </xcrdApi>
</testCampaignResults>
The resulting file using the script below and instant saxon will be:
<?xml version="1.0" encoding="utf-8"?>
<testCampaignResults>
  <header>
     <headerTitle>XCRD Test Campaign Configuration</headerTitle>
     <date>25/08/2005</date>
     <cardConfig>
        <xlsCardNum>0000000023456789</xlsCardNum>
        <efCardSize>32</efCardSize>
        <samKeyInfo>003F</samKeyInfo>
        <efIssuerSize>4C</efIssuerSize>
        <efLoyaltySize>03C8</efLoyaltySize>
        <efCpnSize>0198</efCpnSize>
     </cardConfig>
     <versions>
        <driver>Java V2 card     V1.01</driver>
        <campaign> TEST_CAMPAIGN v1.15</campaign>
        <samDriver>Software SAM</samDriver>
        <modules>
           <xcrd>Xcrd Core        V1.27</xcrd>
           <xdem> XDEM core v1.1 </xdem>
           <xsws> XSWS HCK v2.5  </xsws>
           <xct> XCT  Core V1.1 </xct>
           <xfat> XFAT core v2.0 </xfat>
           <xdat> XDAT core v1.0 </xdat>
        </modules>
     </versions>
     <timeElapsed>20875</timeElapsed>
  </header>
  <xcrdApi>
     <xcrdApiTitle>XCRD APIs Testing Results</xcrdApiTitle>
     <api>
        <apiName result="KO" timeElapsed="20875">GetVer</apiName>
        <testFamily>
           <familyName result="OK"
timeElapsed="4015">GetVer_Nom</familyName>
           <testNum>
              <num result="OK" timeElapsed="4015">GetVer_Nom_T1</num>
              <case>
                 <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C1</caseName>
              </case>
              <case>
                 <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C3</caseName>
                 <caseName>GetVer_Nom_T1_C2</caseName>
              </case>
              <case>
                 <caseName>GetVer_Nom_T1_C3</caseName>
              </case>
           </testNum>
        </testFamily>
        <testFamily>
           <familyName result="KO"
timeElapsed="17672">GetVer_Str</familyName>
           <familyName>GetVer_Fmt</familyName>
           <testNum>
              <num result="KO" timeElapsed="17672">GetVer_Str_T1</num>
              <num>GetVer_Fmt_T1</num>
              <case>
                 <caseName result="KO"
timeElapsed="00:00:02">GetVer_Str_T1_C1</caseName>
                 <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_OpenCardSession</apiCall>
                 <apiCall result="KO" eCode="XCRD_NO_ERROR"
rCode="XCRD_POWER_FAILED">XCRD_OpenSamSession</apiCall>
                 <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_CloseCardSession</apiCall>
                 <caseName>GetVer_Fmt_T1_C1</caseName>
              </case>
              <case>
                 <caseName>GetVer_Fmt_T1_C2</caseName>
              </case>
           </testNum>
        </testFamily>
        <testFamily>
           <familyName>GetVer_Str</familyName>
           <testNum>
              <num>GetVer_Str_T1</num>
              <case>
                 <caseName>GetVer_Str_T1_C1</caseName>
              </case>
              <case>
                 <caseName>GetVer_Str_T1_C2</caseName>
              </case>
              <case>
                 <caseName>GetVer_Str_T1_C31</caseName>
              </case>
           </testNum>
        </testFamily>
     </api>
  </xcrdApi>
</testCampaignResults>

We can see that it's working in almost the cases.
It seems that the script doesn't see that GetVer_Nom_T1_C3 element exists and
add GetVer_Nom_T1_C2 under the same node. GetVer_Nom_T1_C3 element get
mixed up
with GetVer_Nom_T1_C2 element.
GetVer_Str element and GetVer_Fmt get mixed up as well when only one element
should be under testFamily node.
I tried to understand the script given by Joris to try to make it work but i
still don't understand (maybe something wrong with me). I guess the
modification of the script below for making it work with this new xml
structure
should be trivial. Unfortunately, i cant find it.
Does somebody can help me to find the fix.

Thanks.

Thomas

P.S.:
The expected resulting file should look like:
<?xml version="1.0"?>
<testCampaignResults>
 <header>
   <headerTitle>XCRD Test Campaign Configuration</headerTitle>
   <date>25/08/2005</date>
   <cardConfig>
     <xlsCardNum>0000000023456789</xlsCardNum>
     <efCardSize>32</efCardSize>
     <samKeyInfo>003F</samKeyInfo>
     <efIssuerSize>4C</efIssuerSize>
     <efLoyaltySize>03C8</efLoyaltySize>
     <efCpnSize>0198</efCpnSize>
   </cardConfig>
   <versions>
     <driver>Java V2 card     V1.01</driver>
     <campaign> TEST_CAMPAIGN v1.15</campaign>
     <samDriver>Software SAM</samDriver>
     <modules>
       <xcrd>Xcrd Core        V1.27</xcrd>
       <xdem> XDEM core v1.1 </xdem>
       <xsws> XSWS HCK v2.5  </xsws>
       <xct> XCT  Core V1.1 </xct>
       <xfat> XFAT core v2.0 </xfat>
       <xdat> XDAT core v1.0 </xdat>
     </modules>
   </versions>
   <timeElapsed>20875</timeElapsed>
 </header>
 <xcrdApi>
   <xcrdApiTitle>XCRD APIs Testing Results</xcrdApiTitle>
   <api>
     <apiName result="KO" timeElapsed="20875">GetVer</apiName>
     <testFamily>
       <familyName result="OK" timeElapsed="4015">GetVer_Nom</familyName>
       <testNum>
         <num result="OK" timeElapsed="4015">GetVer_Nom_T1</num>
         <case>
           <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C1</caseName>
         </case>
         <case>
           <caseName>GetVer_Nom_T1_C2</caseName>
         </case>
         <case>
           <caseName result="OK"
timeElapsed="00:00:02">GetVer_Nom_T1_C3</caseName>
         </case>
       </testNum>
     </testFamily>
     <testFamily>
       <familyName>GetVer_Fmt</familyName>
       <testNum>
         <num>GetVer_Fmt_T1</num>
         <case>
           <caseName>GetVer_Fmt_T1_C1</caseName>
         </case>
         <case>
           <caseName>GetVer_Fmt_T1_C2</caseName>
         </case>
       </testNum>
     </testFamily>
     <testFamily>
       <familyName result="KO" timeElapsed="17672">GetVer_Str</familyName>
       <testNum>
         <num result="KO" timeElapsed="17672">GetVer_Str_T1</num>
         <case>
           <caseName result="KO"
timeElapsed="00:00:02">GetVer_Str_T1_C1</caseName>
           <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_OpenCardSession</apiCall>
           <apiCall result="KO" eCode="XCRD_NO_ERROR"
rCode="XCRD_POWER_FAILED">XCRD_OpenSamSession</apiCall>
           <apiCall result="OK"
eCode="XCRD_NO_ERROR">XCRD_CloseCardSession</apiCall>
         </case>
         <case>
           <caseName>GetVer_Str_T1_C2</caseName>
         </case>
         <case>
           <caseName>GetVer_Str_T1_C3</caseName>
         </case>
       </testNum>
     </testFamily>
   </api>
 </xcrdApi>
</testCampaignResults>

Quoting Joris Gillis <roac@xxxxxxxxxx>:

On Thu, 01 Sep 2005 11:35:41 +0200, Joris Gillis <roac@xxxxxxxxxx> wrote:

Tempore 04:54:32, die 09/01/2005 AD, hinc in
xsl-list@xxxxxxxxxxxxxxxxxxxxxx scripsit Thomas Tarpin-Lyonnet
<bartleby@xxxxxxxxxx>:

Where file_1.xml are the logs generated by a test campaign and
file_2.xml are
the reference logs generated thanks to a test plan. The aim of doing
this is to
show all the tests that have been defined by the test plan but that we
forgot to
implement and then that don't appear in the logs.

I started working on a solution, but I'm getting stuck at this level (brain meltdown)

After partial recovery of the breakdown (caused by whitespace text nodes), I've managed to produce a solution.

This stylesheet should match your requirements more closely:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="merge">
	<xsl:variable name="test" select="document(test)"/>
	<xsl:variable name="reference" select="document(reference)"/>
	<xsl:apply-templates mode="merge" select="$reference/*">
		<xsl:with-param name="test" select="$test/*"/>
		<xsl:with-param name="reference" select="$reference/*"/>
	</xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="merge">
<xsl:param name="test"/>
<xsl:param name="reference"/>
<xsl:variable name="n"><xsl:number/></xsl:variable>
<xsl:choose>
	<xsl:when test="count(.|$reference)=count($reference)">
	<xsl:copy>
		<xsl:copy-of select="$test[name()=name(current())][.=current()]/@*"/>
		<xsl:apply-templates mode="merge" select="*|text()|$test/*">
			<xsl:with-param name="test"
select="$test[name()=name(current())][number($n)]/*"/>
			<xsl:with-param name="reference" select="*"/>
		</xsl:apply-templates>
	</xsl:copy>
	</xsl:when>
	<xsl:when test="$reference and $test[count(.|current())=1]">
		<xsl:if

test="current()[text()[normalize-space()!='']][not(text()=$reference/text())]
		or not($reference[name()=name(current())][number($n)])">
			<xsl:copy-of select="."/>
		</xsl:if>
	</xsl:when>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>


the input stays the same: <merge> <test>file_1.xml</test> <reference>file_2.xml</reference> </merge>


-- "NN= N?N/N4N1 O ON9 N?ON4N-N= N?N/N4N1" - N#O N:ON1ON7O

Current Thread