2012-04-04 131 views
1

因此,我有一个xml文档,其中不包含完整的跨产品,但我需要xslt来为我填充空白。如果你运行这个xslt,你可以看到GCM应该在ABC之下。我知道我必须计算结果,然后添加一个空白,但我卡住了。带空格的XSLT数据透视表

<root> 
    <Cell> 
    <place>BRM</place> 
    <test>DMC</test> 
    <Score>70</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>GCM</place> 
    <test>DMC</test> 
    <Score>76</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>GRM</place> 
    <test>DMC</test> 
    <Score>72</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>NPM</place> 
    <test>DMC</test> 
    <Score>80</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>PDM</place> 
    <test>DMC</test> 
    <Score>88</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>PTM</place> 
    <test>DMC</test> 
    <Score>58</Score> 
    <Colour>#FFA100</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>SRM</place> 
    <test>DMC</test> 
    <Score>62</Score> 
    <Colour>#FFA100</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>SWC</place> 
    <test>DMC</test> 
    <Score>85</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>RVS</place> 
    <test>DMC</test> 
    <Score>84</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
    <place>BWM</place> 
    <test>SUR</test> 
    <Score>66</Score> 
    <Colour>#FFA100</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup>Survey</testgroup> 
    </Cell> 
    <Cell> 
    <place>PDM</place> 
    <test>SUR</test> 
    <Score>85</Score> 
    <Colour>#008000</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup>Survey</testgroup> 
    </Cell> 
    <Cell> 
    <place>SRM</place> 
    <test>SUR</test> 
    <Score>41</Score> 
    <Colour>#FFA100</Colour> 
    <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
    <testgroup>Survey</testgroup> 
    </Cell> 
</root> 

XSLT

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="html" indent="yes"/> 

    <xsl:key name="muench" match="/root/Cell/place" use="."/> 

    <xsl:key name="test-key" match="/root/Cell/test" use="."/> 

    <xsl:template match="/"> 
    <html> 
     <head> 
     <title>ABC test Report</title> 
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/> 
     </head> 
     <body > 
     <div > 
      <header> 
      <h2 > 
       test group - <xsl:value-of select="/root/Cell/testgroup"/> 
      </h2> 
      </header> 
      <div class="content"> 
      <table > 
       <thead> 
       <tr> 
        <th >Place</th> 
        <xsl:for-each select="/root/Cell/test[generate-id() = generate-id(key('test-key',.)[1])]"> 
        <th > 
         <xsl:value-of select="."/> 
        </th> 
        </xsl:for-each> 
       </tr> 
       </thead> 
       <tbody> 
       <xsl:for-each select="/root/Cell/place[generate-id() = generate-id(key('muench',.)[1])]"> 
        <xsl:call-template name="pivot"> 
        <xsl:with-param name="place" select="."/> 
        </xsl:call-template> 
       </xsl:for-each> 
       </tbody> 
      </table> 
      </div> 
      <footer > 
      <p></p> 
      </footer> 
     </div> 
     </body> 
    </html> 
    </xsl:template> 

    <xsl:template name="pivot"> 
    <xsl:param name="place"/> 
    <tr> 
     <td > 
     <xsl:value-of select="$place"/> 
     </td> 
     <xsl:for-each select="/root/Cell/test[generate-id() = generate-id(key('test-key',.)[1])]"> 
     <xsl:for-each select="/root/Cell[place=$place and test=.]"> 
     <xsl:choose> 
      <xsl:when test="count(.)=1"> 
       <td> 
        <xsl:attribute name="style"> 
        background-color:<xsl:value-of select="Colour"/>; 
        </xsl:attribute> 
        <xsl:value-of select="Score"/>% 
       </td> 
      </xsl:when> 
      <xsl:otherwise> 
       <td> 
       </td> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
     </xsl:for-each> 
    </tr> 
    </xsl:template> 
</xsl:stylesheet> 

输出我想

<html> 
    <table border="1"> 
    <thead> 
     <th>Place</th> 
     <th>DMC</th> 
     <th>SUR</th> 
    </thead> 
    <tbody> 
     <tr> 
     <td>BRM</td> 
     <td> 70</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>BWM</td> 
     <td> </td> 
     <td> 66</td> 
     </tr> 
     <tr> 
     <td>GCM</td> 
     <td> 76</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>GRM</td> 
     <td> 72</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>NPM</td> 
     <td> 80</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>PDM</td> 
     <td> 88</td> 
     <td> 85</td> 
     </tr> 
     <tr> 
     <td>PTM</td> 
     <td> 58</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>RVS</td> 
     <td> 84</td> 
     <td> </td> 
     </tr> 
     <tr> 
     <td>SRM</td> 
     <td> 62</td> 
     <td> 41</td> 
     </tr> 
     <tr> 
     <td>SWC</td> 
     <td> 85</td> 
     <td> </td> 
     </tr> 
    </tbody> 
    </table> 
</html> 
+0

那么,究竟需要的结果是什么?请提供。另请说明转换必须执行的规则。 – 2012-04-04 03:20:55

回答

1

这更短,更简单的改造

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:key name="kTests" match="test" use="."/> 
    <xsl:key name="kCellByPlace" match="Cell" use="place"/> 

    <xsl:variable name="vTests" select= 
     "/*/*/test 
      [generate-id() 
      = 
       generate-id(key('kTests', .)[1]) 
      ] 
     "/> 

    <xsl:template match="/*"> 
     <html> 
      <table border="1"> 
      <thead> 
       <th>Place</th> 
       <xsl:apply-templates select="$vTests"/> 
      </thead> 
      <tbody> 
       <xsl:apply-templates select= 
       "Cell[generate-id() = generate-id(key('kCellByPlace', place))]"> 
       <xsl:sort select="place"/> 
       </xsl:apply-templates> 
      </tbody> 
      </table> 
     </html> 
    </xsl:template> 

    <xsl:template match="test"> 
     <th><xsl:value-of select="."/></th> 
    </xsl:template> 

    <xsl:template match="Cell"> 
     <tr> 
     <td><xsl:value-of select="place"/></td> 
     <xsl:apply-templates select="$vTests" mode="row"> 
     <xsl:with-param name="pCells" select="key('kCellByPlace', place)"/> 
     </xsl:apply-templates> 
     </tr> 
    </xsl:template> 

    <xsl:template match="test" mode="row"> 
     <xsl:param name="pCells"/> 

     <td> 
     <xsl:value-of select= 
     "concat('&#xA0;',$pCells[test=current()]/Score)"/> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

当所提供的XML文档应用:

<root> 
    <Cell> 
     <place>BRM</place> 
     <test>DMC</test> 
     <Score>70</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>GCM</place> 
     <test>DMC</test> 
     <Score>76</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>GRM</place> 
     <test>DMC</test> 
     <Score>72</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>NPM</place> 
     <test>DMC</test> 
     <Score>80</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>PDM</place> 
     <test>DMC</test> 
     <Score>88</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>PTM</place> 
     <test>DMC</test> 
     <Score>58</Score> 
     <Colour>#FFA100</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>SRM</place> 
     <test>DMC</test> 
     <Score>62</Score> 
     <Colour>#FFA100</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>SWC</place> 
     <test>DMC</test> 
     <Score>85</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>RVS</place> 
     <test>DMC</test> 
     <Score>84</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup> Process Plant</testgroup> 
    </Cell> 
    <Cell> 
     <place>BWM</place> 
     <test>SUR</test> 
     <Score>66</Score> 
     <Colour>#FFA100</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup>Survey</testgroup> 
    </Cell> 
    <Cell> 
     <place>PDM</place> 
     <test>SUR</test> 
     <Score>85</Score> 
     <Colour>#008000</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup>Survey</testgroup> 
    </Cell> 
    <Cell> 
     <place>SRM</place> 
     <test>SUR</test> 
     <Score>41</Score> 
     <Colour>#FFA100</Colour> 
     <GenerateDate>2012-04-04 12:46:41</GenerateDate> 
     <testgroup>Survey</testgroup> 
    </Cell> 
</root> 

产生想要的结果

<html> 
    <table border="1"> 
     <thead> 
     <th>Place</th> 
     <th>DMC</th> 
     <th>SUR</th> 
     </thead> 
     <tbody> 
     <tr> 
      <td>BRM</td> 
      <td>&nbsp;70</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>BWM</td> 
      <td>&nbsp;</td> 
      <td>&nbsp;66</td> 
     </tr> 
     <tr> 
      <td>GCM</td> 
      <td>&nbsp;76</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>GRM</td> 
      <td>&nbsp;72</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>NPM</td> 
      <td>&nbsp;80</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>PDM</td> 
      <td>&nbsp;88</td> 
      <td>&nbsp;85</td> 
     </tr> 
     <tr> 
      <td>PTM</td> 
      <td>&nbsp;58</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>RVS</td> 
      <td>&nbsp;84</td> 
      <td>&nbsp;</td> 
     </tr> 
     <tr> 
      <td>SRM</td> 
      <td>&nbsp;62</td> 
      <td>&nbsp;41</td> 
     </tr> 
     <tr> 
      <td>SWC</td> 
      <td>&nbsp;85</td> 
      <td>&nbsp;</td> 
     </tr> 
     </tbody> 
    </table> 
</html> 

说明

  1. 我们创建一个包含一个辅助变量$vTests的所有不同值元素。

  2. 每当我们想要生成tr包含分数在特定地点特定的测试中,我们产生“空” td S代表包含在$vTests所有test元素,其字符串值不等于字符串值特定的test元素,并且恰好当此test元素的字符串值等于当前test元素时,我们生成特定test元素的Score兄弟的字符串值。

+0

这很接近,但是如果一个地方有多个测试分数。它写出一个新的生产线,而不是​​GCM​​43​​72 – jimconstable 2012-04-05 03:39:08

+0

@jimconstable:没有人能猜到 - 这是与当前所提供的XML文档有效的解决方案。由于您没有提供任何其他示例,也没有定义源XML文档的可能格式,因此这是目前问题的完整解决方案。请编辑问题并精确指定XML文档的格式。请说明在可能的情况下应该做什么。这个答案提出了一个完整的问题解决方案。请改善你提问的方式,不要责怪人们不能读懂你的想法。 – 2012-04-05 04:05:26

+0

@jimconstable:现在你已经明确地说明了问题,我已经更新了我的答案,并产生了所需的结果。它也比你自己的答案短,所以这可能值得你注意。 – 2012-04-05 12:23:54

0

感谢Dimetre的帮助。他展示了如何更有效地使用模板并创建变量。然后我用它来编辑他的脚本以提供我正在寻找的输出。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:key name="kTests" match="test" use="."/> 

<xsl:variable name="vTests" select= 
    "/*/*/test 
     [generate-id() 
     = 
      generate-id(key('kTests', .)[1]) 
     ] 
    "/> 

    <xsl:key name="kPlaces" match="place" use="."/> 

<xsl:variable name="vPlaces" select= 
    "/*/*/place 
     [generate-id() 
     = 
      generate-id(key('kPlaces', .)[1]) 
     ] 
    "/> 

<xsl:template match="/*"> 
    <html> 
     <table border="1"> 
     <thead> 
      <th>Place</th> 
      <xsl:apply-templates select="$vTests"> 
      <xsl:sort select="." /> 
      </xsl:apply-templates> 
     </thead> 
     <tbody> 
      <xsl:apply-templates select="$vPlaces"> 
      <xsl:sort select="." /> 
      </xsl:apply-templates> 
     </tbody> 
     </table> 
    </html> 
</xsl:template> 

<xsl:template match="test"> 
    <th><xsl:value-of select="."/></th> 
</xsl:template> 

<xsl:template match="place"> 
    <tr> 
    <td><xsl:value-of select="."/></td> 
    <xsl:apply-templates select="$vTests" mode="row"> 
     <xsl:sort select="." /> 
    <xsl:with-param name="pPlace" select="."/> 
    </xsl:apply-templates> 
    </tr> 
</xsl:template> 

<xsl:template match="test" mode="row"> 
    <xsl:param name="pPlace"/> 
    <td> 
    <xsl:value-of select= 
    "concat('&#xA0;',/root/Cell[test=current() and place=$pPlace]/Score)"/> 
    </td> 
</xsl:template> 

</xsl:stylesheet>