要檢測什麼時候開始一個新的部分,我這樣做:
<xsl:if test="@TheFirstCol>preceding-sibling::*[1]/@TheFirstCol"
難道這是造成很多或再重複?
當然。您選擇的算法是O(N ),並且在有足夠數量的同胞時速度會非常慢,而不管實現語言如何。
下面是使用密鑰的高效算法:
解決方法1:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kC1Value" match="@c1" use="."/>
<xsl:template match="/">
<xsl:for-each select="*/x[generate-id(@c1) = generate-id(key('kC1Value',@c1)[1])]">
<xsl:value-of select="concat('
',@c1)"/>
<xsl:for-each select="key('kC1Value',@c1)">
<xsl:value-of select="'
'"/>
<xsl:for-each select="../@*[not(name()='c1')]">
<xsl:value-of select="concat(' ', .)"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
不幸的是,的XslTransform(.NET 1.1)具有衆所周知的低效率的實施generate-id()
功能。
以下可以是具有的XslTransform更快:
溶液2:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kC1Value" match="@c1" use="."/>
<xsl:template match="/">
<xsl:for-each select="*/x[count(@c1 | key('kC1Value',@c1)[1]) = 1]">
<xsl:value-of select="concat('
',@c1)"/>
<xsl:for-each select="key('kC1Value',@c1)">
<xsl:value-of select="'
'"/>
<xsl:for-each select="../@*[not(name()='c1')]">
<xsl:value-of select="concat(' ', .)"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
當在以下的小的XML文檔應用:
<t>
<x c1="1" c2="0" c3="0" c4="0" c5="0"/>
<x c1="1" c2="0" c3="1" c4="0" c5="0"/>
<x c1="1" c2="2" c3="0" c4="0" c5="0"/>
<x c1="1" c2="1" c3="1" c4="0" c5="0"/>
<x c1="2" c2="0" c3="0" c4="0" c5="0"/>
<x c1="2" c2="0" c3="1" c4="0" c5="0"/>
<x c1="2" c2="2" c3="0" c4="0" c5="0"/>
<x c1="2" c2="1" c3="1" c4="0" c5="0"/>
<x c1="3" c2="0" c3="0" c4="0" c5="0"/>
<x c1="3" c2="0" c3="1" c4="0" c5="0"/>
<x c1="3" c2="2" c3="0" c4="0" c5="0"/>
<x c1="3" c2="1" c3="1" c4="0" c5="0"/>
<x c1="3" c2="0" c3="0" c4="0" c5="0"/>
<x c1="3" c2="0" c3="1" c4="0" c5="0"/>
<x c1="3" c2="2" c3="0" c4="0" c5="0"/>
<x c1="3" c2="1" c3="1" c4="0" c5="0"/>
<x c1="4" c2="0" c3="0" c4="0" c5="0"/>
<x c1="4" c2="0" c3="1" c4="0" c5="0"/>
<x c1="4" c2="2" c3="0" c4="0" c5="0"/>
<x c1="4" c2="1" c3="1" c4="0" c5="0"/>
<x c1="5" c2="0" c3="0" c4="0" c5="0"/>
<x c1="5" c2="0" c3="1" c4="0" c5="0"/>
<x c1="5" c2="2" c3="0" c4="0" c5="0"/>
<x c1="5" c2="1" c3="1" c4="0" c5="0"/>
<x c1="5" c2="0" c3="0" c4="0" c5="0"/>
<x c1="5" c2="0" c3="1" c4="0" c5="0"/>
<x c1="6" c2="2" c3="0" c4="0" c5="0"/>
<x c1="6" c2="1" c3="1" c4="0" c5="0"/>
<x c1="6" c2="0" c3="0" c4="0" c5="0"/>
<x c1="6" c2="0" c3="1" c4="0" c5="0"/>
<x c1="6" c2="2" c3="0" c4="0" c5="0"/>
<x c1="6" c2="1" c3="1" c4="0" c5="0"/>
<x c1="7" c2="0" c3="0" c4="0" c5="0"/>
<x c1="7" c2="0" c3="1" c4="0" c5="0"/>
<x c1="7" c2="2" c3="0" c4="0" c5="0"/>
<x c1="7" c2="1" c3="1" c4="0" c5="0"/>
<x c1="8" c2="0" c3="0" c4="0" c5="0"/>
<x c1="8" c2="0" c3="1" c4="0" c5="0"/>
<x c1="8" c2="2" c3="0" c4="0" c5="0"/>
<x c1="8" c2="1" c3="1" c4="0" c5="0"/>
</t>
兩種溶液所產生的所需的結果:
1
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
2
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
3
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
4
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
5
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
0 0 0 0
0 1 0 0
6
2 0 0 0
1 1 0 0
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
7
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
8
0 0 0 0
0 1 0 0
2 0 0 0
1 1 0 0
從上面的小XML文件我通過複製每個元素6250次(使用另一個XSLT轉換:))生成一個10MB XML文件。
隨着10MB xml文件,並用XslCompiledTransform(.NET 2.0 +)兩種溶液具有下列變換次數:
解決方法1:3.3sec。
解決方案2:2.8秒。
使用XslTransform(.Net 1.1)解決方案2運行1622sec。即大約27分鐘。
我還沒有聽說過那個:) http://en.wikipedia.org/wiki/Schlemiel_the_painter%27s_Algorithm – wprl 2008-10-22 19:19:50
我第一次聽到它在http://www.joelonsoftware.com/articles/fog0000000319.html 哪個(奇怪的循環)是我怎麼發現關於StackOverflow – KnomDeGuerre 2008-10-22 20:03:54