开发者

XSLT sort or group-by?

开发者 https://www.devze.com 2023-02-15 04:36 出处:网络
I have the folllowing xml file: <DATABLOCK> <LINE> <DATA>010000</DATA> <DATA>User1@MSAD</DATA>

I have the folllowing xml file:

<DATABLOCK>
    <LINE>
        <DATA>010000</DATA>
        <DATA>User1@MSAD</DATA>
        <DATA>User2@MSAD</DATA>
        <DEBIT></DEBIT>
        <CREDIT>-0</CREDIT>
    </LINE>
    <LINE>
        <DATA></DATA>
        <DATA>User1@MSAD</DATA>
        <DATA>User2@MSAD</DATA>
        <DEBIT></DEBIT>
        <CREDIT>-0</CREDIT>
    </LINE>
    <LINE>
        <DATA>010002</DATA>
        <DATA>User3@MSAD</DATA>
        <DATA>User2@MSAD</DATA>
        <DEBIT>开发者_JAVA技巧</DEBIT>
        <CREDIT>0</CREDIT>
    </LINE>
    <LINE>
        <DATA></DATA>
        <DATA>User3@MSAD</DATA>
        <DATA>User2@MSAD</DATA>
        <DEBIT></DEBIT>
        <CREDIT>-0</CREDIT>
    </LINE>
    <LINE>
        <DATA></DATA>
        <DATA>User3@MSAD</DATA>
        <DATA>User2@MSAD</DATA>
        <DEBIT></DEBIT>
        <CREDIT>0</CREDIT>
    </LINE>
    <LINE>
        <DATA>010003</DATA>
        <DATA>User4@MSAD</DATA>
        <DATA>User5@MSAD</DATA>
        <DEBIT></DEBIT>
        <CREDIT>640,650</CREDIT>
    </LINE>
    <LINE>
        <DATA></DATA>
        <DATA>User4@MSAD</DATA>
        <DATA>User5@MSAD</DATA>
        <DEBIT>567,103</DEBIT>
        <CREDIT></CREDIT>
    </LINE>
    <LINE>
        <DATA></DATA>
        <DATA>User4@MSAD</DATA>
        <DATA>User5@MSAD</DATA>
        <DEBIT>73,547</DEBIT>
        <CREDIT></CREDIT>
    </LINE>
</DATABLOCK>

This file is the output for which I can't readily modify, it would take longer to figure out the coding that produces the xml data than creating a modified display format. The data represents a journals report with the values in the DATA nodes equal to journal number, approved by, posted by, debit amount, credit amount. I've edited the standard report XSL file to this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
    <h1>Posted Journals:</h1>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Journal</th>
        <th>Approved By</th>
        <th>Posted By</th>
      </tr>
      <xsl:for-each select="DATABLOCK/LINE">
      <tr>
                <xsl:for-each select="DATA">
                        <TD><xsl:value-of select="."/></TD>
                </xsl:for-each>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

My problem is ignoring subsequent LINE where the first DATA element is empty. I don't need debit or credit so my desired output is this:

Journal Approved By Posted By
010000     User1@MSAD    User2@MSAD
010002      User3@MSAD   User2@MSAD
010003      User4@MSAD   User5@MSAD

I'm completely new at XSLT and find bits and pieces online that seem like they might apply but don't fully understand the syntax and how to modify it for my scenario.


If they are already grouped and sorted, then it looks like you can just render the rows that have a value for the first DATA element and skip the rest:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />

<xsl:template match="DATABLOCK">
  <html>
  <body>
    <h1>Posted Journals:</h1>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Journal</th>
        <th>Approved By</th>
        <th>Posted By</th>
      </tr>
      <xsl:apply-templates />
    </table>
  </body>
  </html>
  </xsl:template>

  <!--Do not render LINEs that do not have a value for the first DATA element-->
  <xsl:template match="LINE[not(normalize-space(DATA[1]))]"/>

  <!--Each LINE element will be renderd as a Row-->
  <xsl:template match="LINE">
    <tr><xsl:apply-templates select="DATA"/></tr>
  </xsl:template>

  <!--Each DATA element will be a column -->
  <xsl:template match="DATA">
    <td><xsl:value-of select="."/></td>
  </xsl:template>
</xsl:stylesheet>


Just change the for-each condition to

<xsl:for-each select="DATABLOCK/LINE[not(DATA[1]/text()='')]">

This restricts the for-each to process only lines having a non-empty text node in the first DATA element.

0

精彩评论

暂无评论...
验证码 换一张
取 消