Reputation: 1038
Before I detail out my problem, I am currently transforming on xml to another using XSLT. But the thing is I want to know whether it is possible in the xslt sheet to use the resulted xml for some computation.
For instance, if I have the following XSLT,
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root/metadata">
<xsl:variable name="_countEmp" select="count(header/employees)" />
<xsl:variable name="_countCont" select="count(header/employees/Contribution)" />
<XMLDATA>
<XMLHEADER>
<SERVICEID>RTLOAD001</SERVICEID>
<SOURCE>MOBILE</SOURCE>
<VERSION>2.0</VERSION>
<RELEASEDATE>20171101</RELEASEDATE>
<VALIDFROM>20171101</VALIDFROM>
<VALIDTO>99991231</VALIDTO>
</XMLHEADER>
<FORMRETURNS>
<FORMMAIN>
<B_A_JOB_NO/>
<LTP_FLAG>N</LTP_FLAG>
<LOGIN_ID/>
</FORMMAIN>
<FORMDETAILS>
<xsl:choose>
<xsl:when test="($_taxtype = 'PACO')">
<RETURNDATA>
<RETURNDETAILS formtype='PAYEA'>
<B_A_CONTRACT_NO/>
<B_FORMTYPE>X</B_FORMTYPE>
<B_POSTING_REF/>
</RETURNDETAILS>
<ANNEXDETAILS>
<TABLE tablename="PAYEA_L">
<rows>
<xsl:for-each select="header/employees">
<xsl:choose>
<xsl:when test="(status = 'N' or (status = 'A' and WithHeldAmount > 0))">
<row>
<ZDTL_NID><xsl:value-of select="nidCardNumber" /></ZDTL_NID>
<ZDTL_LASTNAME><xsl:value-of select="lastName" /></ZDTL_LASTNAME>
<ZDTL_ONAME><xsl:value-of select="firstName" /></ZDTL_ONAME>
</row>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</rows>
<numRows><xsl:value-of select="$_countEmp"/></numRows>
</TABLE>
</ANNEXDETAILS>
</RETURNDATA>
</xsl:when>
</xsl:choose>
</FORMDETAILS>
</FORMRETURNS>
</XMLDATA>
</xsl:template>
</xsl:stylesheet>
I would like to know if it is possible not to output the node RETURNDATA, if the rows node is blank.
Thanks, Ashley
Upvotes: 0
Views: 303
Reputation: 163352
There's also an XSLT 3.0 way of doing this, that was designed specifically for streaming, but that can also be handy in non-streaming applications.
I would like to know if it is possible not to output the node RETURNDATA, if the rows node is blank.
First, you can avoid outputting the rows element if it's going to be empty:
<xsl:where-populated>
<rows>
<xsl:for-each....>
...
</xsl:for-each>
</rows>
</xsl:where-populated>
Then you can do the same to avoid outputting an empty TABLE:
<xsl:where-populated>
<TABLE>
<xsl:where-populated>
<rows>
....
and the same for the ANNEXDETAILS
.
Then you can avoid outputting the RETURNDETAILS
if it's not going to be followed by an ANNEXDETAILS
:
<RETURNDATA>
<xsl:on-non-empty>
<RETURNDETAILS>
....
</RETURNDETAILS>
</xsl:on-non-empty>
<xsl:where-populated>
<ANNEXDETAILS>
....
It gets a bit convoluted when there are this many elements involved, but it can be handy when you really need a one-pass solution.
Upvotes: 1
Reputation: 167571
As you have tagged the question as xslt-2.0 I assume you use an XSLT 2.0 processor and then you can of course use a variable at any place to create a temporary tree which you can then process further, so in your XSLT you could for instance create a variable
<xsl:template match="/">
<xsl:variable name="result1">
<xsl:apply-templates/>
</xsl:variable>
</xsl:template>
and that way you have the result of processing the primary input in that variable, you simply need to make sure you process it further with e.g.
<xsl:template match="/">
<xsl:variable name="result1">
<xsl:apply-templates/>
</xsl:variable>
<!-- example computation -->
<xsl:value-of select="'result has', count($result1//foo), 'foo elements'"/>
</xsl:template>
That assumes you have further templates in place to process the primary input. Depending on your existing code it might help to separate processing steps using modes.
As for the sample you have added to your question, it does not seem to be necessary to write two steps, if you add to your condition <xsl:when test="($_taxtype = 'PACO')">
the test you have inside with e.g.
<xsl:when test="($_taxtype = 'PACO') and header/employees[(status = 'N' or (status = 'A' and WithHeldAmount > 0))]">
then the RETURNDATA
element should only be output if the inner code produces any row
elements.
Upvotes: 1