Reputation: 1091
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
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