2011-11-21 62 views
3

我想知道這個謂詞([1])如何在muenchian分組中被硬編碼爲1。經過大量搜索後,我對這個概念並不清楚。它被解釋爲當前節點,與由密鑰返回的第一組進行比較。 爲什麼總是比較第一個密鑰匹配? 另外爲什麼我們再給contact[count(. | key('contacts-by-surname', surname)[1]) = 1], the =1 part?再次硬編碼。我提到以下鏈接muenchian分組

http://www.jenitennison.com/xslt/grouping/muenchian.html

回答

1

我想知道這個謂詞([1])是如何硬編碼爲1總是在 muenchian分組。

這是簡單

key()函數生成的所有節點對於給定組,我們希望從任何團體舉一個節點。

不保證所有的組都會有兩個或更多的節點 - 有些節點可能只有一個節點。

這就是爲什麼從每個組中取出第一個(也可能是唯一的)節點是安全和方便的。

我們同樣可以做分組採取最後節點從每組(但這將是低效率):

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

<xsl:key name="kNumByMod3" match="num" 
    use=". mod 3"/> 

<xsl:template match= 
    "num[generate-id() 
     = 
     generate-id(key('kNumByMod3', . mod 3)[last()]) 
     ] 
    "> 


    3k + <xsl:value-of select=". mod 3"/>: 
<xsl:text/> 
    <xsl:copy-of select="key('kNumByMod3', . mod 3)"/> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

當這個XML文檔施加:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

產生想要的,正確分組的結果

3k + 2: 
<num>02</num> 
<num>05</num> 
<num>08</num> 


    3k + 0: 
<num>03</num> 
<num>06</num> 
<num>09</num> 


    3k + 1: 
<num>01</num> 
<num>04</num> 
<num>07</num> 
<num>10</num> 
+0

完美。另外通過一些實驗發現,下面三個做分組1)contact [count(。| key('contacts-by-surname',surname)[1])= 1]「> 2)contact [count(。| key ('contacts-by-surname',surname)[2])= 1]「> 3)contact [count(。| key('contacts-by-surname',surname'[last()])= 1]」 > – Suresh

+0

是的,謂詞是測試兩個節點是否相同(同一個節點),也可以用'generate-id()'來完成,XPath 2.0用'is'運算符表示 –

+0

@ user1004770:如果您對此主題感興趣,請查看此答案:http://stackoverflow.com/questions/133092/how-do-you-identify-duplicate-elements-in-an-xpath-2 -0-sequence –

2

比方說,我們有一個鍵定義<xsl:key name="contacts-by-surname" match="contact" use="surname"/>,則表達式key('contacts-by-surname', 'Doe')爲您提供了所有contact元素,其中的surnameDoe設置節點。表達式key('contacts-by-surname', 'Doe')[1]爲您提供了該組中的第一個contact

現在用for-eachapply-templates處理所有contact元素時,我們通常會想辦法來識別每個組中的第一contact元素。這可以通過<xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]"><xsl:for-each select="contact[generate-id() = generate-id(key('contacts-by-surname', surname)[1])]">來實現。

如果您的要求不同,並且您想要識別每個組中的最後一個項目,那麼您當然可以使用不同的謂詞,如<xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[last()]) = 1]"><xsl:for-each select="contact[generate-id() = generate-id(key('contacts-by-surname', surname)[last()])]">

0

基本算法是有兩個嵌套循環。外部循環從每個組中選擇一個代表性節點,並且內部循環選擇該組中的所有節點(包括被選爲代表性的節點)。從組中選擇一個代表性節點的最簡單方法是選擇第一個,因此謂詞爲[1]

+1

@_Michael:在我的解決方案中有* no *循環,它仍然是* grouping *。我認爲對於XSLT 3.0,我們仍然可以提供*分組函數*,它消除了'xsl最明顯的缺點:for-each-group「 - 缺少composa吳春明.. –

相關問題