I need some help on the XSLT please.
I got an XML file and I need to report some data twice in the file and soem data need to be filtered out.
and on the footer I need to report exactly how many rows are in the file.
Can someone please help me here?Thanks
Here is my XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ns0:File xmlns:ns0="file">
<ns0:Records>
<ns0:Main>
<ns0:Info>
<ns0:InternalCode>1</ns0:InternalCode>
<ns0:Name>test1</ns0:Name>
<ns0:Factor>2.000000000000</ns0:Factor>
<ns0:Type>a</ns0:Type>
</ns0:Info>
</ns0:Main>
<ns0:Main>
<ns0:Info>
<ns0:InternalCode>2</ns0:InternalCode>
<ns0:Name>test2</ns0:Name>
<ns0:Factor>10.000000000000</ns0:Factor>
<ns0:Type>c</ns0:Type>
</ns0:Info>
</ns0:Main>
<ns0:Main>
<ns0:Info>
<ns0:InternalCode>3</ns0:InternalCode>
<ns0:Name>test3</ns0:Name>
<ns0:Factor>13.000000000000</ns0:Factor>
<ns0:Type>b</ns0:Type>
</ns0:Info>
</ns0:Main>
<ns0:Main>
<ns0:Info>
<ns0:InternalCode>4</ns0:InternalCode>
<ns0:Name>test4</ns0:Name>
<ns0:Factor>1.000000000000</ns0:Factor>
<ns0:Type>a</ns0:Type>
</ns0:Info>
</ns0:Main>
<ns0:Main>
<ns0:Info>
<ns0:InternalCode>5</ns0:InternalCode>
<ns0:Name>test5</ns0:Name>
<ns0:Factor>1.000000000000</ns0:Factor>
<ns0:Type>f</ns0:Type>
</ns0:Info>
</ns0:Main>
</ns0:Records>
<ns0:Footer>
<ns0:Time>10:54:40</ns0:Time>
<ns0:NumberOfRecords>5</ns0:NumberOfRecords>
</ns0:Footer>
</ns0:File>
And here is my XSLT:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="file">
<xsl:output method="text"
encoding="ASCII"/>
<xsl:template match="ns0:Main">
<xsl:variable name="substractone">
<xsl:value-of select="ns0:Info/ns0:Factor-1"/>
</xsl:variable>
<xsl:if test=" ns0:Factor !=0 and ns0:Type !='c' and $substractone !=0 ">
<xsl:choose>
<xsl:when test="ns0:Type = 'a'">
<xsl:value-of select="ns0:InternalCode"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Factor"/>
<xsl:text>
</xsl:text>
<!-- repeat in a new line -->
<xsl:value-of select="ns0:InternalCode"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Factor"/>
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="ns0:InternalCode"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ns0:Factor"/>
<xsl:text>
</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="ns0:Footer">
<!--Footer row-->
<xsl:text>
</xsl:text>
<xsl:text>*</xsl:text>
<xsl:value-of select="ns0:NumberOfRecords"/>
<!--record total-->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
As you can see the ns0:NumberOfRecords would have returned 5 here but in fact this file got 4 rows (filtering out type=c and 2 rows for each type=a)
Can someone please tell me how I can get the number of rows in the file correctly?
As you can see the ns0:NumberOfRecords would have returned 5 here but in fact this file got 6 rows (filtering out type=c and 2 rows for each type=a)
Instead of
<xsl:value-of select="ns0:NumberOfRecords"/>
write
<xsl:value-of select="count(//ns0:Type[. != 'c']) + count(//ns0:Type[. = 'a'])"/>
Then, you get the following output:
*6
Other issues with your XML and code:
xsl:if
and xsl:choose
evaluates to "true". Thus, the only thing that is output is the total number of records. This is because of the context . By context I mean the following. Your template matches ns0:Main
elements and that is therefore "your" position in the tree. Now, a line like this one:
<xsl:if test=" ns0:Factor !=0 and ns0:Type !='c' ">
actually looks for ns0:Factor
and ns0:Type
elements that are immediate children of the ns0:Main
element. But, as you know, there are no such elements. Instead, ns0:Factor
and ns0:Type
are children of ns0:Info
. You have to account for this fact:
<xsl:if test=" ns0:Info/ns0:Factor !=0 and ns0:Info/ns0:Type !='c' ">
Or perhaps it might be easier to change the template match:
<xsl:template match="ns0:Main/ns0:Info">
If you make either of those changes, the output is:
1,test1,1.000000000000
1,test1,1.000000000000
3,test3,13.000000000000
4,test4,1.000000000000
4,test4,1.000000000000
5,test5,1.000000000000
*6
xmlns:xsl="http://www.w3.org/1999/XSL/Transform")
in your stylesheet </ns0:Records>
element that closes prematurely and prevents the file from being well-formed Actually I found this Number of rows in a flat file transformed from xml using xslt
this will count the no. of line breaks and tell you how many rows are in the file:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.