0

I have a for each loop and a if condition under for loop. I want to increment the value of variable i everytime if the if condition is true. Based on value of variable i I want to implement some logic. Below is the code

<xsl:variable name="i" select="0"/>
<xsl:for-each select="Request/ModifyProductsAndPackages/NrcList/Nrc">
<xsl:variable name="typeIdNrcVar" select="TypeIdNrc"/>

<xsl:if test="count(/Request/WaiveNrcList/WaiveNrc/TypeIdNrc[text()=$typeIdNrcVar])=0">
   <xsl:variable name="i" select="$i + 1"/>
   <xsl:if test ="$i=1">
    do something
   </xsl:if>
</xsl:if>
</xsl:for-each/>

Here the value of i could not be incremented. can anyone please suggest as how should i accomplish above task. Thanks for help.

Below is xml structure

<Request>
<ModifyProductsAndPackages>
<NrcList>
   <Nrc>
     <TypeIdNrc>14046</TypeIdNrc>
     <ServiceInternalId>98602440</ServiceInternalId>
     <ServiceInternalIdResets>0</ServiceInternalIdResets>
     <ViewableOnly>1</ViewableOnly>
   </Nrc>
   <Nrc>
     <TypeIdNrc>12002</TypeIdNrc>
     <ServiceInternalId>98602440</ServiceInternalId>
     <ServiceInternalIdResets>0</ServiceInternalIdResets>
     <ViewableOnly>1</ViewableOnly>
   </Nrc>
   <Nrc>
     <TypeIdNrc>13006</TypeIdNrc>
     <ServiceInternalId>98602440</ServiceInternalId>
     <ServiceInternalIdResets>0</ServiceInternalIdResets>
     <ViewableOnly>1</ViewableOnly>
   </Nrc>
   <Nrc>
     <TypeIdNrc>14098</TypeIdNrc>
     <ServiceInternalId>98602440</ServiceInternalId>
     <ServiceInternalIdResets>0</ServiceInternalIdResets>
     <ViewableOnly>1</ViewableOnly>
   </Nrc>
 </NrcList>     
 </ModifyProductsAndPackages>
<WaiveNrcList>
<WaiveNrc>
  <TypeIdNrc>12002</TypeIdNrc>
  <ServiceInternalId>98602440</ServiceInternalId>
  <ServiceInternalIdResets>0</ServiceInternalIdResets>
</WaiveNrc>
<WaiveNrc>
  <TypeIdNrc>13256</TypeIdNrc>
  <ServiceInternalId>98602440</ServiceInternalId>
  <ServiceInternalIdResets>0</ServiceInternalIdResets>
</WaiveNrc>
<WaiveNrc>
  <TypeIdNrc>14046</TypeIdNrc>
  <ServiceInternalId>98602440</ServiceInternalId>
  <ServiceInternalIdResets>0</ServiceInternalIdResets>
</WaiveNrc>
</WaiveNrcList>
</Request>

The end result I want to achieve is NrcList = NrcList-WaiveNrcList. I want to exclude on the matching records on the basis of TypeIdNrc, ServiceInternalId, ServiceInternalIdResets Below is the result xml

<Request>
  <NrcList>
    <Nrc>
      <TypeIdNrc>13006</TypeIdNrc>
      <ServiceInternalId>98602440</ServiceInternalId>
      <ServiceInternalIdResets>0</ServiceInternalIdResets>
<ViewableOnly>1</ViewableOnly>
</Nrc>
<Nrc>
<TypeIdNrc>14098</TypeIdNrc>
<ServiceInternalId>98602440</ServiceInternalId>
<ServiceInternalIdResets>0</ServiceInternalIdResets>
<ViewableOnly>1</ViewableOnly>
    </Nrc>
</NrcList>
</Request> 

Another approach:

3
  • You need to use recursive templates for this. Please describe in more detail exactly what you want to achieve. What variable do you want to increment? How do you plan to leave the loop (when all elements are done? when $i is a certain value? what does $i mean?) Commented Jun 4, 2014 at 1:48
  • I want to increment variable i and if value of i is 1 then I want to implement some logic else do something else logic Commented Jun 4, 2014 at 3:46
  • In XSLT, variables cannot be modified. Why don't you edit your question and explain in more detail what are you trying to accomplish - not how are you hoping to go about it. Commented Jun 4, 2014 at 4:58

1 Answer 1

1

Here's an example that copies only the Nrc elements that do not have a matching record in WaiveNrcList- based on matching TypeIdNrc:

XSLT 1.0

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

<xsl:key name="waive" match="WaiveNrc" use="TypeIdNrc" />

<xsl:template match="/">
    <Request>
        <NrcList>
            <xsl:for-each select="Request/ModifyProductsAndPackages/NrcList/Nrc[not(key('waive', TypeIdNrc))]">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </NrcList>
    </Request>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, the result is:

<?xml version="1.0" encoding="UTF-8"?>
<Request>
   <NrcList>
      <Nrc>
         <TypeIdNrc>13006</TypeIdNrc>
         <ServiceInternalId>98602440</ServiceInternalId>
         <ServiceInternalIdResets>0</ServiceInternalIdResets>
         <ViewableOnly>1</ViewableOnly>
      </Nrc>
      <Nrc>
         <TypeIdNrc>14098</TypeIdNrc>
         <ServiceInternalId>98602440</ServiceInternalId>
         <ServiceInternalIdResets>0</ServiceInternalIdResets>
         <ViewableOnly>1</ViewableOnly>
      </Nrc>
   </NrcList>
</Request>
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks Michael for your reply. In this case the key is TypeIdNrc,ServiceInternalId and ServiceInternalIdResets. Is there a way to match on all the 3 fields.
@user3366906 Yes, use a concatenation of all three - both in the key definition (the use attribute) and when calling the key() function.
` <NrcList1> <xsl:for-each select="Request/ModifyProductsAndPackages/NrcList/Nrc[not(key('waive', concat(TypeIdNrc,ServiceInternalId,ServiceInternalIdResets)))]"> <xsl:copy-of select="."/> </xsl:for-each> </NrcList1>`
<xsl:key name="waive" match="WaiveNrc" use="concat(TypeIdNrc,ServiceInternalId,ServiceInternalIdResets)"/> Is that right?
@user3366906 Yes, except that in order to prevent false positives, you should place a delimiter between the values, e.g. concat(TypeIdNrc, '|', ServiceInternalId, '|', ServiceInternalIdResets).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.