使用XSLT

时间:2016-04-13 00:40:04

标签: xml xslt xslt-1.0

我有一个XML文件,它有几个兄弟节点,一个存储时间戳<TIMESTAMP>,另一个存储分类代码<Code>,另一个存在整数值<Count>。我想计算与<Count>相关的<Code>值与<TIMESTAMP>相关的差异。有多个代码......我已经简化了XML。然后,此计算的结果将填充HTML表中的两个单元格之一。我被限制使用XSLT 1.0将XML转换为HTML。

以下是XML的摘录:

XML

<?xml version="1.0" encoding="UTF-8"?>
<surveyGDB>
  <table>
    <tablename>QaQcPoints
      <record>
        <OBJECTID>1</OBJECTID>
        <TIMESTAMP>20150722 09:18:43</TIMESTAMP>
        <Code>tp</Code>
        <Count>50</Count>
      </record>
      <record>
        <OBJECTID>2</OBJECTID>
        <TIMESTAMP>20150722 09:18:43</TIMESTAMP>
        <Code>bl</Code>
        <Count>110</Count>
      </record>
      <record>
        <OBJECTID>5</OBJECTID>
        <TIMESTAMP>20150730 01:05:22</TIMESTAMP>
        <Code>bl</Code>
        <Count>100</Count>
      </record>
      <record>
        <OBJECTID>6</OBJECTID>
        <TIMESTAMP>20150730 01:05:22</TIMESTAMP>
        <Code>tp</Code>
        <Count>55</Count>
      </record>
    </tablename>
  </table>
</surveyGDB>

输出HTML表应如下所示:

HTML

----------------------------
| Code   | Added | Deleted |
----------------------------
| tp     | 5     | 0       |
----------------------------
| bl     | 0     | 10      |
----------------------------

我假设我需要对<TIMESTAMP>值进行排序,并找到排序值的第一个和最后一个位置。这是我查找与最早时间戳相关联的<Count>值的相关XSL代码:

XSL

<xsl:for-each select="/surveyGDB/table/tablename/record" />
    <xsl:sort select="TIMESTAMP" />
        <xsl:choose>
            <xsl:when test="position() = 1">
                <xsl:value-of select="Count" />
            </xsl:when>
        </xsl:choose>

但是,我如何找到最后一个时间戳,然后如何按<Count>对计算出的<Code>值进行分组?

关于如何最好地解决这个问题的任何建议?

1 个答案:

答案 0 :(得分:1)

首先查看muenchian grouping

尝试这样的事情:

<xsl:key name="krecord" match="record" use="Code"/>

<xsl:template match="tablename">
  <xsl:for-each select="record [ 
                        count ( key('krecord',./Code)[1] | . ) = 1]">

    <xsl:variable name="this" select="." />
    <!-- group stuff -->

    <xsl:for-each select=" key('krecord',$this/Code)">
      <!-- group member stuff -->

    </xsl:for-each>  
  </xsl:for-each>
</xsl:template>

然后添加第一个,最后一个,添加差异&#34;计算&#34;为了一个基本的想法尝试:

<xsl:key name="krecord" match="record" use="Code"/>

<xsl:template match="tablename">
    <xsl:for-each select="record [ 
                          count ( key('krecord',./Code)[1] | . ) = 1]">

      <xsl:variable name="this" select="." />
      <!-- group stuff -->
      <xsl:variable name="first" >
        <xsl:for-each select=" key('krecord',$this/Code)">
          <xsl:sort select="TIMESTAMP" />
          <xsl:choose>
              <xsl:when test="position() = 1">
                  <xsl:value-of select="Count" />
              </xsl:when>
          </xsl:choose>
        </xsl:for-each>
      </xsl:variable>

      <xsl:variable name="last" >
        <xsl:for-each select=" key('krecord',$this/Code)">
          <xsl:sort select="TIMESTAMP" />
          <xsl:choose>
              <xsl:when test="position() = last()">
                  <xsl:value-of select="Count" />
              </xsl:when>
          </xsl:choose>
        </xsl:for-each>
      </xsl:variable>

      <xsl:variable name="diff" select="$first - $last " />
      <xsl:choose>
        <xsl:when test="$diff >= 0" >
              <xsl:value-of select="Code" />, <xsl:value-of select="$diff" />,0;    
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="Code" />, 0, <xsl:value-of select="$diff" />;
        </xsl:otherwise>       
      </xsl:choose>

  </xsl:for-each>
</xsl:template>