XSLT如何在列而不是行中显示数据

时间:2010-10-18 16:13:54

标签: xslt

我在XML中有以下数据

<data> 
 <record> 
  <id>1</id> 
  <name>David</name> 
  <age>40</age>  
 </record> 
 <record> 
  <id>2</id> 
  <name>Tully</name> 
  <age>38</age> 
 </record> 
 <record> 
  <id>3</id>  
  <name>Solai</name> 
  <age>32</age> 
 </record> 
 <record> 
  <id>4</id>  
  <name>Michael</name> 
  <age>49</age> 
 </record> 
 <record> 
  <id>5</id>  
  <name>Tony</name> 
  <age>19</age> 
 </record> 
 <record> 
  <id>6</id>  
  <name>Ray</name> 
  <age>26</age> 
 </record> 
 <record> 
  <id>7</id>  
  <name>Leeha</name> 
  <age>13</age> 
 </record> 
</data> 

并希望显示如下数据:

ID    1     2   
Name  David Tully
Age   40    38

我怎样才能在XSLT中做到这一点?

2 个答案:

答案 0 :(得分:4)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="data">
        <table>
            <xsl:apply-templates select="*[1]"/>
        </table>
    </xsl:template>
    <xsl:template match="record[1]/*" priority="1">
        <tr>
            <th>
                <xsl:value-of select="name()"/>
            </th>
            <xsl:call-template name="td"/>
        </tr>
    </xsl:template>
    <xsl:template match="record/*" name="td">
        <td>
            <xsl:value-of select="."/>
        </td>
        <xsl:apply-templates select="following::*[count(../*)+1]"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<table>
    <tr>
        <th>id</th>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
    </tr>
    <tr>
        <th>name</th>
        <td>David</td>
        <td>Tully</td>
        <td>Solai</td>
        <td>Michael</td>
        <td>Tony</td>
        <td>Ray</td>
        <td>Leeha</td>
    </tr>
    <tr>
        <th>age</th>
        <td>40</td>
        <td>38</td>
        <td>32</td>
        <td>49</td>
        <td>19</td>
        <td>26</td>
        <td>13</td>
    </tr>
</table>

编辑:只是为了表明这可能是一个不那么琐碎的问题,那么具有更宽松架构的XML树(缺少记录中的某些字段)呢?

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kElementByName" match="record/*" use="name()"/>
    <xsl:template match="text()"/>
    <xsl:template match="data">
        <table>
            <xsl:apply-templates/>
        </table>
    </xsl:template>
    <xsl:template match="record/*[count(.|key('kElementByName',name())[1])=1]">
        <tr>
            <th>
                <xsl:value-of select="name()"/>
            </th>
            <xsl:apply-templates select="../../record" mode="td">
                <xsl:with-param name="pName" select="name()"/>
            </xsl:apply-templates>
        </tr>
    </xsl:template>
    <xsl:template match="record" mode="td">
        <xsl:param name="pName"/>
        <td>
            <xsl:value-of select="*[name()=$pName]"/>
        </td>
    </xsl:template>
</xsl:stylesheet>

使用此输入:

<data>
    <record>
        <id>1</id>
        <name>David</name>
    </record>
    <record>
        <name>Tully</name>
        <age>38</age>
    </record>
    <record>
        <id>3</id>
        <age>32</age>
    </record>
</data>

输出:

<table>
    <tr>
        <th>id</th>
        <td>1</td>
        <td></td>
        <td>3</td>
    </tr>
    <tr>
        <th>name</th>
        <td>David</td>
        <td>Tully</td>
        <td></td>
    </tr>
    <tr>
        <th>age</th>
        <td></td>
        <td>38</td>
        <td>32</td>
    </tr>
</table>

答案 1 :(得分:0)

假设您正在输出HTML,您可以循环记录以将它们排列在彼此之下:

<xsl:template match="data">
   <table>
      <tr>
         <td>ID</td>
         <xsl:apply-templates select="record" mode="id" />
      </tr>
      <tr>
         <td>Name</td>
         <xsl:apply-templates select="record" mode="name" />
      </tr>
      <tr>
          <td>Age</td>
           <xsl:apply-templates select="record" mode="age" />
      </tr>
   </table>
</xsl:template>

<xsl:template match="record" mode="id">
   <td><xsl:value-of select="id" /></td>
</xsl:template>

<xsl:template match="record" mode="name">
   <td><xsl:value-of select="name" /></td>
</xsl:template>

<xsl:template match="record" mode="age">
   <td><xsl:value-of select="age" /></td>
</xsl:template>