用xslt创建可变长度的光束

时间:2017-01-30 18:21:30

标签: css xml xslt

来自以下xml数据:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="kandidaten.xsl" type="text/xsl"?> 
<auswertung>
    <kandidat>
        <name>Peter</name>
        <punkte>67</punkte>
    </kandidat>
    <kandidat>
        <name>Karl</name>
        <punkte>87</punkte>
    </kandidat>
    <kandidat>
        <name>Anita</name>
        <punkte>36</punkte>
    </kandidat>
    <kandidat>
        <name>Rosi</name>
        <punkte>67</punkte>
    </kandidat>
    <kandidat>
        <name>Heiner</name>
        <punkte>50</punkte>
    </kandidat>
    <kandidat>
        <name>Paul</name>
        <punkte>45</punkte>
    </kandidat>
</auswertung>

我想用xslt:

创建以下输出

enter image description here

为此,我编写了以下xslt代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">


<xsl:template match="auswertung">
    <html>
        <head>
            <title>Kandidaten</title>
        </head>
        <body>
            <h1>Kandidaten und ihre Punkte</h1>
            <hr/>
            <table>
                <xsl:apply-templates select="kandidat">
                    <xsl:sort select="punkte" order="descending"></xsl:sort>
                </xsl:apply-templates>
            </table>

        </body>
    </html>
</xsl:template>

<xsl:template match="kandidat">

    <tr>
        <td>
            <xsl:value-of select="name/text()"/>
        </td>

<!-- second columns of table is supposed to contain the -->
<!-- points  ("punkte") of the respective candidate ("kandidat") -->
        <td>

<!-- second column contains a paragraph whose background-color is blue -->
            <p bgcolor="#0000ff">
               <xsl:call-template name="create_empty_space">
                    <xsl:with-param name="count" select="punkte/text()"/>
                    <xsl:with-param name="number" select="punkte/text()"/>
               </xsl:call-template>
           </p>         
        </td>                           
    </tr>
</xsl:template>

<xsl:template name="create_empty_space">
    <xsl:param name="count"/>
    <xsl:param name="number"/>

<!-- print number (points achieved by candidate) in the middle of the beam -->                 
<xsl:if test="$count = round($number div 2)">
        <font color="#ffff00">
            <xsl:value-of select="$number"/>
        </font>
    </xsl:if>
    <xsl:if test="$count > 0"> 


  <!-- amount of empty space created is supposed to depend on the number of -->
  <!--points, therefore function "create_empty_space" is called recursively-->
  <!-- depending on the number of points -->
  <!--... example: if points==20, function is called 20 times -->                                 

<xsl:text> </xsl:text>
        <xsl:call-template name="create_empty_space">
            <xsl:with-param name="count" select="$count - 1"/>
            <xsl:with-param name="number" select="$number"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>


</xsl:stylesheet>

当我运行代码时,所有光束都具有相同的大小。 如何使光束的长度与相应候选者的点数相对应?

1 个答案:

答案 0 :(得分:1)

由于您在XML输入中使用xml-stylesheet,我怀疑您是否真的使用2.0处理器。

与Martin建议的一样,第一项宽度应为100%,其余项目的宽度应根据第一项(最大)计算。

这是您的XSLT的修改版本......

XSLT 1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>

  <!--This is easier in XSLT 2.0:
  <xsl:variable name="maxPoints" select="max(/*/kandidat/punkte)"/>
  -->
  <xsl:variable name="maxPoints">
    <xsl:for-each select="/*/kandidat">
      <xsl:sort select="punkte" order="descending"/>
      <xsl:if test="position() = 1">
        <xsl:value-of select="punkte"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="auswertung">
    <html>
      <head>
        <title>Kandidaten</title>
      </head>
      <body>
        <h1>Kandidaten und ihre Punkte</h1>
        <hr/>
        <table style="width: 100%">
          <xsl:apply-templates select="kandidat">
            <xsl:sort select="punkte" order="descending"/>
          </xsl:apply-templates>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="kandidat">
    <tr>
      <td style="width: 1%">
        <xsl:value-of select="name"/>
      </td>

      <!-- second columns of table is supposed to contain the -->
      <!-- points  ("punkte") of the respective candidate ("kandidat") -->
      <td>

        <!-- second column contains a paragraph whose background-color is blue -->
        <div style="text-align: center;width: {round(punkte div $maxPoints * 100)}%;color: #ffff00;background-color: #0000ff;">
          <xsl:value-of select="punkte"/>
        </div>         
      </td>                           
    </tr>
  </xsl:template>

</xsl:stylesheet>

<强>输出

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Kandidaten</title>
   </head>
   <body>
      <h1>Kandidaten und ihre Punkte</h1>
      <hr>
      <table style="width: 100%">
         <tr>
            <td style="width: 1%">Karl</td>
            <td>
               <div style="text-align: center;width: 100%;color: #ffff00;background-color: #0000ff;">87</div>
            </td>
         </tr>
         <tr>
            <td style="width: 1%">Peter</td>
            <td>
               <div style="text-align: center;width: 77%;color: #ffff00;background-color: #0000ff;">67</div>
            </td>
         </tr>
         <tr>
            <td style="width: 1%">Rosi</td>
            <td>
               <div style="text-align: center;width: 77%;color: #ffff00;background-color: #0000ff;">67</div>
            </td>
         </tr>
         <tr>
            <td style="width: 1%">Heiner</td>
            <td>
               <div style="text-align: center;width: 57%;color: #ffff00;background-color: #0000ff;">50</div>
            </td>
         </tr>
         <tr>
            <td style="width: 1%">Paul</td>
            <td>
               <div style="text-align: center;width: 52%;color: #ffff00;background-color: #0000ff;">45</div>
            </td>
         </tr>
         <tr>
            <td style="width: 1%">Anita</td>
            <td>
               <div style="text-align: center;width: 41%;color: #ffff00;background-color: #0000ff;">36</div>
            </td>
         </tr>
      </table>
   </body>
</html>

编辑:您还可以使用CSS类清理样式表并输出一点......

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>

  <!--This is easier in XSLT 2.0:
  <xsl:variable name="maxPoints" select="max(/*/kandidat/punkte)"/>
  -->
  <xsl:variable name="maxPoints">
    <xsl:for-each select="/*/kandidat">
      <xsl:sort select="punkte" order="descending"/>
      <xsl:if test="position() = 1">
        <xsl:value-of select="punkte"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="auswertung">
    <html>
      <head>
        <title>Kandidaten</title>
        <style type="text/css">
          .name {
            width: 10%;
          }
          .punkte {
            text-align: center;
            color: #ffff00;
            background-color: #0000ff;
          }
          table.kandidat {
            width: 100%;
          }
        </style>
      </head>

      <body>
        <h1>Kandidaten und ihre Punkte</h1>
        <hr/>
        <table class="kandidat">
          <xsl:apply-templates select="kandidat">
            <xsl:sort select="punkte" order="descending"/>
          </xsl:apply-templates>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="kandidat">
    <tr>
      <td class="name">
        <xsl:value-of select="name"/>
      </td>
      <td>
        <div style="width: {round(punkte div $maxPoints * 100)}%;"
          class="punkte">
          <xsl:value-of select="punkte"/>
        </div>         
      </td>                           
    </tr>
  </xsl:template>