Counting a tag – ‘count’ function and the tag value – ‘sum’ function
The
function ‘count’ is used to count an entity in the current ‘for-each’ ‘testplan’.
So, since
we are at the ‘testplan’ level, we are counting the total occurrences of the
‘testcase_id’ within that ‘testplan’. This could also be accomplished by using
only
<xsl:value-of
select="count(.//testcase_id)"/>
This
command is equally functional, just that the former one shows the hierarchy. There
is a count of ‘tc_test_design_status’. This is a conditional count, which
counts all the test cases when the testcase has the custom attribute of
‘tc_test_design_status’ set as ‘Complete’. See the XML below (under a testcase
tag):
Another
example of conditional copying can be seen as follows, when we count the number
of ‘passed’ testcases (indicated with value ‘p’ in the Example.xml)
The value
for testcase to be passed must come from XML as follows:
Remember
that all these counts are within ‘testplan’, so when we use ‘//’ within that,
we go directly to the ‘tcexecution_status’ tag and count when its value is ‘p’.
Did you
notice the XPath expression? Here it is:
‘.//build/platform/testcase/testcase_id’
On the
similar lines, we might sometimes need to sum the value within the tags.
Consider the following XML:
<AllDCs>
<DCDetails>
<DC>DC 8</DC>
<TTLTCs>30</TTLTCs>
<TTLBTCs>3</TTLBTCs>
<TTLPTCs>26</TTLPTCs>
<TTLFTCs>1</TTLFTCs>
</DCDetails>
<DCDetails>
<DC>DC 1</DC>
<TTLTCs>11</TTLTCs>
<TTLBTCs>0</TTLBTCs>
<TTLPTCs>11</TTLPTCs>
<TTLFTCs>0</TTLFTCs>
</DCDetails>
<AllDCs>
If we have to get the sum of <TTLPTCs> for both the
DCDetails, then we need to use the function as:
<xsl:value-of select = “sum(DCDetails/TTLPTCs)”>
assuming that we are at the DCDetails level. The difference
between count and sum is that ‘count’ is used to count the number of occurrences
of a tag, while sum is used to add the contents of a tag.
We can also use conditional sum. For example, consider the
following XML:
<DCRecord>
<DC>DC 8</DC>
<DCBuildRecord>
<BuildNumber>1</BuildNumber>
<PlanDetails>
<Phase>2013-R3-Dec</Phase>
<Test_Type>DC
System</Test_Type>
<BP>Purchase</BP>
<LOB>Multi - LOB</LOB>
<TTLs>
<TTLTCs>153</TTLTCs>
<TTLBTCs>11</TTLBTCs>
<TTLPTCs>142</TTLPTCs>
<TTLFTCs>0</TTLFTCs>
<TTLIPTCs>0</TTLIPTCs>
<TTLDTCs>0</TTLDTCs>
<TTLWTCs>0</TTLWTCs>
</TTLs>
</PlanDetails>
</DCBuildRecord>
</DCRecord>
<DCRecord>
<DC>DC 8</DC>
<DCBuildRecord>
<BuildNumber>3</BuildNumber>
<PlanDetails>
<Phase>2013-R3-Dec</Phase>
<Test_Type>Integration</Test_Type>
<BP>Payments</BP>
<LOB>Multi - LOB</LOB>
<TTLs>
<TTLTCs>147</TTLTCs>
<TTLBTCs>0</TTLBTCs>
<TTLPTCs>116</TTLPTCs>
<TTLFTCs>1</TTLFTCs>
<TTLIPTCs>0</TTLIPTCs>
<TTLDTCs>24</TTLDTCs>
<TTLWTCs>6</TTLWTCs>
</TTLs>
</PlanDetails>
</DCBuildRecord>
</DCRecord>
To get the totals
depending on various conditions following code was used:
<TTLTCs>
<xsl:value-of select =
"sum(//PlanDetails[../../DC = 'DC 8' and Test_Type = 'Integration' and BP
= 'Purchase' and (Phase = '2014-R3' or Phase =
'ICP_Ph1.001.500.000')]//TTLTCs)"/>
</TTLTCs>
<xsl:text>
</xsl:text>
<TTLBTCs>
<xsl:value-of select =
"sum(//PlanDetails[../../DC = 'DC 8' and Test_Type = 'Integration' and BP
= 'Purchase' and (Phase = '2014-R3' or Phase =
'ICP_Ph1.001.500.000')]//TTLBTCs)"/>
</TTLBTCs>
<xsl:text>
</xsl:text>
<TTLPTCs>
<xsl:value-of select =
"sum(//PlanDetails[../../DC = 'DC 8' and Test_Type = 'Integration' and BP
= 'Purchase' and (Phase = '2014-R3' or Phase =
'ICP_Ph1.001.500.000')]//TTLPTCs)"/>
</TTLPTCs>
<xsl:text>
</xsl:text>
<TTLFTCs>
<xsl:value-of select =
"sum(//PlanDetails[../../DC = 'DC 8' and Test_Type = 'Integration' and BP
= 'Purchase' and (Phase = '2014-R3' or Phase =
'ICP_Ph1.001.500.000')]//TTLFTCs)"/>
</TTLFTCs>
The output of the
above file could be an XML file shown below:
<TTLTCs>50<TTLTCs>
<TTLBTCs>20<TTLTCs>
<TTLPTCs>20<TTLTCs>
<TTLFTCs>10<TTLTCs>
Carefully note the use
of brackets and conditions and the use of ../ in the above example.
‘Choose:when:otherwise’ construct
Under the
section – “Getting the values – conditional ‘xsl:value-of’ tag” we counted
testcases that had the custom attribute of ‘tc_test_design_status’ set as ‘Complete’.
For the group that had an exception, we actually had Test Design Status set at
the ‘testplan’ level, so there is nothing to count. The value will be set at ‘testplan’
level. Hence for that the code was written as follows:
Here we
have new construct called choose:when:otherwise, that is similar to
if:then:else.
‘Choose’ is
just selecting something ‘when’ a condition is true; ‘otherwise’ the other
statement is executed (something else is selected).
It is
evident that the condition is put at the ‘testplan’ level and if the value is
set correctly ‘Complete’, we will count all testcases within that ‘testplan’.
Counting at a different level of hierarchy
The next
requirement was to get the counts at the level of ‘testplans’ and also the
builds. For ‘testplans’, the above points explain how to get the totals. But,
now when we go down to the level of builds, then we can get totals only at the
builds level, in the following way:
Ignore the
conditions in between; they are similar to previously discussed code. Just take
note of how we have gone one level down to builds. But now, when we will use
the ‘./’ construct, we will get all the attributes (fields) at the build level
only. How to get the values at the ‘testplan’ level (custom attributes, ‘testplan_name’,
‘testplan_id’, Total TCs at Test Plan level etc.)? Simple, we will use the
construct ‘../’, - to go one level up from build and get the values. This will
be applied to all fields that we need.
As it is
evident from the above code snippet, we have just included an extra ‘../’ to
get ‘datasource_description’ and ‘repository_id’ values (as compared to that
when we did the same thing at the ‘testplan’ level). Also, to get the values at
the ‘testplan’ level, ‘../’ has been included in place of ‘./’ since we are now
looking at one level up the ‘build’. Similarly the following code will give us
totals at the ‘testplan’ level even though ‘for-each’ has gone down to ‘build’
level.
Read the
above statement simply as – Give total number of ‘testcase_id’s within one
level up the current level.
Variables in XSLT
Use of
variables in XSLT is different from the way we use them in conventional
structured programming languages such as C, C++, Java etc. There is a scope
limitation for each variable, out of which it cannot be used. You cannot
reassign a variable within that scope and neither can you re-declare it.
This tag
will put the value of ‘testplan_id’ into variable TP1. To use a variable we
need to prefix it with a $ sign as follows:
Variables
are immutable, meaning that when once assigned with a value, they cannot be
changes. In a way, they behave like constants.
No comments:
Post a Comment