Suresh
Suresh

Reputation: 1091

xslt looping for different scenario based on pairs

As per suggestions, posting this question in a seperate thread. The question is a continuation, to the below link

xslt-loop-count-context-value-from-top-xml

We wanted to produce the below xml as output(some changes in the outputxml). the tag, "errorsandwarnings" should be present in case atleast one error or warning is present,"allerrors" tag when atleast one error is present, "allwarnings" tag when atleast one warning is present

<Root>
  <errorsandwarnings>
    <allerrors>
      <error>apple</error>
      <error>apple</error>
    </allerrors>
    <allwarnings>
      <warning>apple</warning>
    </allwarnings>
  </errorsandwarnings>
  <success>apple</success>
</Root>

Upvotes: 1

Views: 136

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

This transformation:

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

     <xsl:variable name="vErrors" select=
     "/*/Envelope[position() mod 2 = 1]
                   [(.|following-sibling::Envelope[1])
                                          /criticalerror
                   ]"/>

     <xsl:variable name="vWarnings" select=
     "/*/Envelope[position() mod 2 = 1]
                   [(.|following-sibling::Envelope[1])
                                              /milderror
                   ]"/>

     <xsl:variable name="vErrorsWarnings" select=
     "$vErrors | $vWarnings"/>

     <xsl:variable name="vSuccess" select=
        "/*/Envelope
            [position() mod 2 = 1]
              [not((.|following-sibling::Envelope[1])
                    /*[self::criticalerror or self::milderror]
                  )
              ]
     "/>

     <xsl:template match="/*">
         <Root>
           <xsl:if test="$vErrorsWarnings">
            <errorsandwarnings>
             <xsl:apply-templates select="$vErrors"/>
             <xsl:apply-templates select="$vWarnings"/>
            </errorsandwarnings>
           </xsl:if>

           <xsl:apply-templates select="$vSuccess"/>
         </Root>
     </xsl:template>

     <xsl:template match=
      "Envelope
        [position() mod 2 = 1
       and
         success
       and
         following-sibling::Envelope[1]/success
        ]">

      <success>
       <xsl:call-template name="getTitle"/>
      </success>
     </xsl:template>

     <xsl:template match=
      "Envelope
        [position() mod 2 = 1
       and
         (.|following-sibling::Envelope[1])/criticalerror
        ][1]">
       <allerrors>
         <xsl:apply-templates mode="error" select="$vErrors"/>
       </allerrors>
     </xsl:template>


     <xsl:template match="Envelope" mode="error">
      <error>
       <xsl:call-template name="getTitle"/>
      </error>
     </xsl:template>

     <xsl:template match=
      "Envelope
        [position() mod 2 = 1
       and
         (.|following-sibling::Envelope[1])/milderror
       and
         not((.|following-sibling::Envelope[1])/criticalerror)
        ][1]">
       <allwarnings>
         <xsl:apply-templates mode="warning" select="$vWarnings"/>
       </allwarnings>
     </xsl:template>

     <xsl:template match="Envelope" mode="warning">
      <warning>
       <xsl:call-template name="getTitle"/>
      </warning>
     </xsl:template>

     <xsl:template name="getTitle">
      <xsl:value-of select=
        "(.|following-sibling::Envelope[1])
             /Header/ineed[normalize-space()]
                                           [1]
        "/>
     </xsl:template>
     <xsl:template match="text()"/>
</xsl:stylesheet>

when applied on the XML document provided in the previous question:

<Root>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <milderror></milderror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
</Root>

produces the wanted, correct result:

<Root>
   <errorsandwarnings>
      <allerrors>
         <error>apple</error>
         <error>apple</error>
      </allerrors>
      <allwarnings>
         <warning>apple</warning>
      </allwarnings>
   </errorsandwarnings>
   <success>apple</success>
</Root>

Upvotes: 1

Related Questions