XML to HTML table with XSLT

后端 未结 4 1507
梦如初夏
梦如初夏 2020-12-17 02:56

I need to be able to turn a flat xml data sets into html tables, and I\'m having trouble finding syntax examples that will fit my need. I would like to use one stylesheet th

相关标签:
4条回答
  • 2020-12-17 03:11

    A straight-forward and short solution:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
         <table><xsl:apply-templates select="row"/></table>
     </xsl:template>
    
     <xsl:template match="row[1]">
      <tr><xsl:apply-templates select="*" mode="header"/></tr>
      <xsl:call-template name="standardRow"/>
     </xsl:template>
    
     <xsl:template match="row" name="standardRow">
      <tr><xsl:apply-templates select="*"/></tr>
     </xsl:template>
    
     <xsl:template match="row/*">
      <td><xsl:apply-templates select="node()"/></td>
     </xsl:template>
    
     <xsl:template match="row/*" mode="header">
      <th><xsl:value-of select="name()"/></th>
     </xsl:template>
    </xsl:stylesheet>
    

    when applied on the first provided XML document:

    <rows>
        <row>
            <AccountId>BlPUAA0</AccountId>
            <AccountName>Initech</AccountName>
            <AcocuntStatus>Client</AcocuntStatus>
        </row>
        <row>
            <AccountId>CJxIAAW</AccountId>
            <AccountName>Intertrode</AccountName>
            <AcocuntStatus>Prospect</AcocuntStatus>
        </row>
    </rows>
    

    the wanted, correct result is produced:

    <table>
       <tr>
          <th>AccountId</th>
          <th>AccountName</th>
          <th>AcocuntStatus</th>
       </tr>
       <tr>
          <td>BlPUAA0</td>
          <td>Initech</td>
          <td>Client</td>
       </tr>
       <tr>
          <td>CJxIAAW</td>
          <td>Intertrode</td>
          <td>Prospect</td>
       </tr>
    </table>
    

    when applied on the second provided XML document:

    <rows>
        <row>
            <AccountId>BlPUAA0</AccountId>
            <AccountName>Initech</AccountName>
        </row>
        <row>
            <AccountId>CJxIAAW</AccountId>
            <AccountName>Intertrode</AccountName>
        </row>
    </rows>
    

    again the desired, correct result is produced:

    <table>
       <tr>
          <th>AccountId</th>
          <th>AccountName</th>
       </tr>
       <tr>
          <td>BlPUAA0</td>
          <td>Initech</td>
       </tr>
       <tr>
          <td>CJxIAAW</td>
          <td>Intertrode</td>
       </tr>
    </table>
    
    0 讨论(0)
  • 2020-12-17 03:19

    Few days ago I post an article, hope it can help you: http://web.swfideas.com/?p=12191

    Asuming this data:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Edited by XMLSpy -->
    <table-node>
      <tbody>
        <tr>
          <td>[C1R1]</td>
          <td>[C2R1]</td>
        </tr>
        <tr>
          <td>[C1R2]</td>
          <td>[C2R2]</td>
        </tr>
        <tr>
          <td>[C1R3]</td>
          <td>[C2R3]</td>
        </tr>
      </tbody>
    </table-node>
    

    Now, the core, our XSLT template:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Coded by SWFideas -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- table template -->
    <xsl:template match="table-node">
        <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;">
            <xsl:for-each select="tbody">
                <tbody>
                    <xsl:for-each select="tr">
                        <tr>
                            <xsl:for-each select="td">
                                <td style="border:solid #000000 1px; padding: 5px;">
                                    <xsl:value-of select="."/>
                                </td>
                            </xsl:for-each>                     
                        </tr>                 
                    </xsl:for-each>
                </tbody>
            </xsl:for-each>
        <table>
    </xsl:template>
    </xsl:stylesheet>
    

    In this first approach I’m avoiding to use COLSPAN and another real-life properties (implementation soon, I promise). So the result if we apply our XSLT will be like this:

    <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;">
        <tbody>
            <tr>
                <td style="border:solid #000000 1px; padding: 5px;">[C1R1]</td>
                <td style="border:solid #000000 1px; padding: 5px;">[C2R1]</td>
            </tr>
            <tr>
                <td style="border:solid #000000 1px; padding: 5px;">[C1R2]</td>
                <td style="border:solid #000000 1px; padding: 5px;">[C2R2]</td>
            </tr>
            <tr>
                <td style="border:solid #000000 1px; padding: 5px;">[C1R3]</td>
                <td style="border:solid #000000 1px; padding: 5px;">[C2R3]</td>
            </tr>
        </tbody>
    </table>
    

    You can try it here: http://www.xsltcake.com/slices/gNfh6i/2

    0 讨论(0)
  • 2020-12-17 03:23

    This stylesheet:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <table>
                <xsl:apply-templates select="rows/row[1]" />
            </table>
        </xsl:template>
        <xsl:template match="row">
            <tr>
                <xsl:apply-templates mode="th" />
            </tr>
            <xsl:apply-templates select="../row" mode="td" />
        </xsl:template>
        <xsl:template match="row/*" mode="th">
            <th>
                <xsl:value-of select="local-name()" />
            </th>
        </xsl:template>
        <xsl:template match="row" mode="td">
            <tr>
                <xsl:apply-templates />
            </tr>
        </xsl:template>
        <xsl:template match="row/*">
            <td>
                <xsl:apply-templates />
            </td>
        </xsl:template>
    </xsl:stylesheet>
    

    Applied to:

    <rows>
        <row>
            <AccountId>BlPUAA0</AccountId>
            <AccountName>Initech</AccountName>
            <AcocuntStatus>Client</AcocuntStatus>
        </row>
        <row>
            <AccountId>CJxIAAW</AccountId>
            <AccountName>Intertrode</AccountName>
            <AcocuntStatus>Prospect</AcocuntStatus>
        </row>
    </rows>
    

    Produces:

    <table>
        <tr>
            <th>AccountId</th>
            <th>AccountName</th>
            <th>AcocuntStatus</th>
        </tr>
        <tr>
            <td>BlPUAA0</td>
            <td>Initech</td>
            <td>Client</td>
        </tr>
        <tr>
            <td>CJxIAAW</td>
            <td>Intertrode</td>
            <td>Prospect</td>
        </tr>
    </table>
    

    And applied to:

    <rows>
      <row>
        <AccountId>BlPUAA0</AccountId>
        <AccountName>Initech</AccountName>
      </row>
      <row>
        <AccountId>CJxIAAW</AccountId>
        <AccountName>Intertrode</AccountName>
      </row>
    </rows>
    

    Produces:

    <table>
        <tr>
            <th>AccountId</th>
            <th>AccountName</th>
        </tr>
        <tr>
            <td>BlPUAA0</td>
            <td>Initech</td>
        </tr>
        <tr>
            <td>CJxIAAW</td>
            <td>Intertrode</td>
        </tr>
    </table>
    

    Alternatively, this stylesheet produces the same output using a conditional and one fewer template:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <table>
                <xsl:apply-templates select="rows/row" />
            </table>
        </xsl:template>
        <xsl:template match="row">
            <xsl:if test="position()=1">
                <tr>
                    <xsl:apply-templates mode="th" />
                </tr>
            </xsl:if>
            <tr>
                <xsl:apply-templates />
            </tr>
        </xsl:template>
        <xsl:template match="row/*" mode="th">
            <th>
                <xsl:value-of select="local-name()" />
            </th>
        </xsl:template>
        <xsl:template match="row/*">
            <td>
                <xsl:apply-templates />
            </td>
        </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
  • 2020-12-17 03:31

    I had the urge to try to solve this shortly after posting the question, and here is what I came up with. I guess it makes you wait 24 hours before you can answer it yourself.

    <?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" omit-xml-declaration="yes"/>
      <xsl:template match="/">
        <table>
          <tr>
            <xsl:for-each select="rows/row[1]/*">
              <th>
                <xsl:value-of select ="local-name()"/>
              </th>
            </xsl:for-each>
          </tr>
          <xsl:for-each select="rows/row">
            <tr>
              <xsl:for-each select="*">
                <td>
                  <xsl:value-of select="."/>
                </td>
              </xsl:for-each>
            </tr>
          </xsl:for-each>
        </table>
      </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
提交回复
热议问题