2013-11-22 93 views
1

新手問題。我要創建這樣一個交叉表報告:使用下面的(簡化)XML 使用XSL處理來自平面數據結構的層次結構

 
         SC  TIN 
Total     3  2 
    South East   2  0 
    Gold Coast   2  0 
    North     1  2 
    Cairns    0  1 
    Townsville   1  1 

<DATASETLIST> 
<DATASET entity="SC"> 
    <ROW> 
    <District>GOLD COAST</District> 
    <Region>SOUTH EAST</Region> 
    </ROW> 
    <ROW> 
    <District>GOLD COAST</District> 
    <Region>SOUTH EASTERN</Region> 
    </ROW> 
    <ROW> 
    <District>TOWNSVILLE</District> 
    <Region>NORTH</Region> 
    </ROW> 
</DATASET> 
<DATASET entity="TIN"> 
    <ROW> 
    <District>TOWNSVILLE</District> 
    <Region>NORTH</Region> 
    </ROW> 
    <ROW> 
    <District>CAIRNS</District> 
    <Region>NORTH</Region> 
    </ROW> 
</DATASET> 
</DATASETLIST> 

其實我已經得到了主報告然而工作的層次結構是硬編碼(如計數SC的鏈接到「黃金海岸」),但由於數據可能較差,我可能會錯過一些節點,因此我想根據數據構建一個獨特的層次結構,然後我可以爲每個節點調用我的「count」模板。

我有一點(見下文),我可以產生一個區域排序列表,但它不是唯一的,並且各區不在每個區域內排序。我在想,我可以創建一個獨特的層次結構變量,然後用xsl:for-each邏輯處理它。

但我不知道這是可能的還是推薦的方法。這可能是一個非常簡單的解決方案,但我不知道如何去做。請在簡單(並明確解釋)的條款謝謝任何答案。

<xsl:for-each select="//Region[not(Region=preceding-sibling::Region)]"> 
    <xsl:sort select="."/> 
    <xsl:for-each select="."> 
     <xsl:value-of select="."/> - 
     <xsl:for-each select="../District"> 
      <xsl:value-of select="."/><br/> 
     </xsl:for-each> 
    </xsl:for-each> 
</xsl:for-each> 

回答

1

這就是你怎麼做到的。不過,恐怕這並不容易,也很直接。輸入XMl的結構使得訪問相關節點變得更加困難。

例如,在幾個地方,您需要訪問自然不在上下文中的節點。爲了解決這個問題,我使用了變量和參數。

但它是非常通用的,即您可以處理任意數量的DATASETS,RegionsDistricts。它創建一個HTML表格來顯示計數。

<?xml version="1.0" encoding="utf-8"?> 

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:element name="html"> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="DATASETLIST"> 
    <xsl:element name="head"> 
    <xsl:element name="title"> 
     <xsl:text>DATASET counts</xsl:text> 
    </xsl:element> 
    </xsl:element> 
    <xsl:element name="body"> 
    <xsl:element name="table"> 
     <xsl:attribute name="border">1</xsl:attribute> 
     <xsl:call-template name="tbl"/> 
    </xsl:element> 
    </xsl:element> 
</xsl:template> 

<xsl:template name="tbl"> 
    <xsl:param name="regions" select="distinct-values(DATASET/ROW/Region)"/> 
    <xsl:param name="rows" select="DATASET/ROW"/> 
    <xsl:param name="datasets" select="DATASET"/> 

    <!--header row--> 
    <xsl:element name="tr"> 
    <xsl:element name="th"/> 
    <xsl:for-each select="$datasets"> 
     <xsl:element name="th"> 
      <xsl:value-of select="@entity"/> 
     </xsl:element> 
    </xsl:for-each> 
    </xsl:element> 
    <!--Totals row--> 
    <xsl:element name="tr"> 
    <xsl:element name="td"> 
     <xsl:element name="b"> 
      <xsl:text>Total</xsl:text> 
     </xsl:element> 
    </xsl:element> 
    <xsl:for-each select="$datasets"> 
     <xsl:element name="td"> 
      <xsl:value-of select="count(ROW)"/> 
     </xsl:element> 
    </xsl:for-each> 
    </xsl:element> 
    <xsl:element name="tr"/> 
    <!--region rows--> 
    <xsl:for-each select="$regions"> 
    <xsl:variable name="region" select="."/>  
    <xsl:element name="tr"> 
     <xsl:element name="td"> 
      <xsl:element name="b"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
     </xsl:element> 
     <xsl:for-each select="$datasets"> 
      <xsl:element name="td"> 
       <xsl:value-of select="count(ROW/Region[.=$region])"/> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:element> 
    <!--district rows--> 
    <xsl:for-each select="distinct-values($rows[Region=$region]/District)"> 
     <xsl:variable name="district" select="."/> 
     <xsl:element name="tr"> 
      <xsl:element name="td"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
      <xsl:for-each select="$datasets"> 
       <xsl:element name="td"> 
       <xsl:value-of select="count(ROW/District[.=$district])"/> 
       </xsl:element> 
      </xsl:for-each> 
     </xsl:element> 
    </xsl:for-each> 
    <xsl:element name="tr"/> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 
+0

非常感謝您付出的努力。不幸的是,我僅限於XSLT 1.0,所以我試圖解決使用不同值的問題,但您提供了一個很好的起點。 – madturbocow

+0

不客氣。對於將來的問題,您可以使用標籤'xslt-1.0'來獲得對您來說立即有用的答案。 –

+0

我是初學者。我將來會尋找正確的標籤。 – madturbocow