简体   繁体   中英

Count number of rows in XSLT1.0

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:

  • none of your 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
  • you do not declare the XSLT namespace ( xmlns:xsl="http://www.w3.org/1999/XSL/Transform") in your stylesheet
  • in your input XML, there is a surplus </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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM