2012-11-18 64 views
2

我必須編寫一個XSLT文檔,該文檔可以與任何XML文檔一起使用,並將結果顯示在HTML表格中。表中的列全都取決於XML文檔中有多少個標籤。我正在嘗試使用計算在xslt中有多少個標籤遵循父標籤

<xsl:value-of select="count(/*/*/)"/> 

來計算標籤的數量。

但我想,如果比如我有:

<film> 
     <title></title> 
     <year></year> 
     <actor></actor> 
    </film> 
    <film> 
     <title></title> 
     <year></year> 
     <actor></actor> 
    </film> 

結果將是沒有,因爲它當前正在顯示3 6。任何解決這個問題的方法?

+0

如何使用'follow ::'軸?雖然我不太明白你在這裏想要什麼,所以我可能完全錯誤。 – biziclop

回答

1

I.假設0可以通過utlizing的distinct-values表達式中使用以獲得正確的答案

  1. ,你有像一個良好的XML文檔:

。 。 。 。

<films> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    </film> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    </film> 
</films> 

0.2。該film所有元素均具有相同數量的相同名稱的列,那麼你只需要:

count(/*/*[1]/*) 

這將產生XML文檔的頂級元素的第一個孩子 - 元素的子元素的數量:

3 

II。另一種可能性:不同的film元素具有不同數量的子元素,其中一個元素具有確定表表的總列數的所有子元素。

<films> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    </film> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    <rating/> 
    <director/> 
    </film> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    <rating/> 
    </film> 
</films> 

然後,使用XPath 2.0,使用:

max(/*/*/count(*)) 

該生產兒童的最大數量的XML文檔的頂級元素的孩子有:

5 

三,最後,如果有可能,沒有任何film元素都包含在列中的所有元素,然後使用(什麼ABach已經建議):

count(distinct-values(/*/*/*/name())) 
+0

非常感謝:)這工作完美 – xarababe

+0

@xarababe,不客氣。 –

0

一XSLT 1.0/XPath 1.0中

我不相信有一種方法用純XPath 1.0中做到這一點(因爲你正在尋找是不同的元素名稱,我認爲,在不任何特定的順序[無論如何,我不喜歡依賴於某種秩序])。

也就是說,您可以使用基於密鑰的XSLT 1.0解決方案來解決問題。

當該XSLT 1.0文檔:

<films> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    </film> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    </film> 
</films> 

...的:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output omit-xml-declaration="no" indent="yes" method="text"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:key name="kFilmChildren" match="film/*" use="name()"/> 

    <xsl:template match="/"> 
    <xsl:value-of 
     select="count(//film/*[ 
       generate-id() = 
       generate-id(key('kFilmChildren', name())[1]) 
     ])"/> 
    </xsl:template> 
</xsl:stylesheet> 

...抵靠示例XML(包裝在一個根元素)施加想要的結果是:

3 

如果我們將同樣的樣式表對一個稍微修改XML:

<films> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    <test/> 
    </film> 
    <film> 
    <title/> 
    <year/> 
    <actor/> 
    <test/> 
    <test2/> 
    </film> 
</films> 

......再次,正確的答案是生產:

5 

注:鑑於你沒有顯示完整的文檔,我通過使用//表達式彌補了這些缺乏知識。然而,這可能是一個非常大的樹木附近昂貴的操作;你會做得更好,讓你更具體。


二, XSLT 2.0/XPath 2.0

Pure XPath 2。

count(distinct-values(//film/*/name())) 

XSLT驗證::

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output omit-xml-declaration="no" indent="yes" method="text" /> 
    <xsl:strip-space elements="*" /> 

    <xsl:template match="/"> 
    <xsl:value-of select="count(distinct-values(//film/*/name()))" /> 
    </xsl:template> 

</xsl:stylesheet> 

結果:

3 
0

你的文件實際上包含16個標籤:8個開始標記和8月底標籤。所以我懷疑「計數標籤」並不是你真正的要求。由於您的術語不正確,我們只能猜測您的真實需求。我懷疑可能是爲每個不同的元素名稱生成一行表,其中包含具有該名稱的元素數的計數。這將是:

<table> 
    <xsl:for-each-group select="//*" group-by="name()"> 
    <tr> 
     <td><xsl:value-of select="current-grouping-key()"/></td> 
     <td><xsl:value-of select="count(current-group()"/></td> 
    </tr> 
    </xsl:for-each-group> 
</table>