このコードには多くの非効率性があり、私は小さなものから始めます。
ONE
<xsl:variable name="ROW_">
<xsl:value-of select="count(./preceding-sibling::*) + 1"/>
</xsl:variable>
XSL絶対に使用しないでください:あなたは本当に一時的なXMLのツリー構造を作成する場合を除き、価値の:含まれるXSLを持つ変数を。これは、文字列に変換テキストノードに文字列を変換し、ドキュメントノードを作成し、それをあなたが(数()付き)整数値を計算している、あなたの方法をやって
<xsl:variable name="ROW_" select="count(./preceding-sibling::*) + 1"/>
を書くためにはるかに効率的ですテキストノードを文書ノードに追加するステップと、述語[position()=$ROW_]
で変数を使用すると、すべてのテキストノードを見つけて連結し、その結果を整数に変換することによって、文書ノードの文字列値を取得します。変数を最初に整数にバインドする方が良いでしょう!
TWO
<xsl:for-each select='/Header/*[starts-with (text(), 'Car')] '>
これは、外側のxsl以内に表示されますのために、それぞれ、それが繰り返し実行されますが、/Header/*[starts-with (text(), 'Car')]
の結果は毎回同じであるので、それはで何かに依存しませんループ。スマート・オプティマイザは、式をループから外します(これは、「/」が毎回同じルート・ノードを選択することに依存するため、これは自明ではありません。これは、for-eachの外側が単一-documentノード集合)。そのスマートなオプティマイザに頼るのではなく、式/Header/*[starts-with (text(), 'Car')]
を変数にバインドします。
THREE
<xsl:value-of select="/data/row[position()=$ROW_]/@*[position()=$COLUMN_]"/>
これはおそらく重要なものです:すべての行を処理ループ内で、あなたはすべての行を処理ループを持っているので、あなたはすぐにOを持っている(nは^ 2)パフォーマンス:入力サイズを2倍にすると、実行時間は4倍になります。
また、Saxon-EEのようなスマートなオプティマイザはこれを並べ替えるでしょう(コンストラクトはSQLのジョインのようなものであり、ジョインの最適化は十分に確立された技術です)。しかし、オープンソースのプロセッサを使用している場合は、オプティマイザがスマートではない可能性があるので、手動で最適化する必要があります。これはやりにくいことではありません。選択されているのは、外側のfor-eachが現在処理中のものになります。
FOUR
@*[position()=$COLUMN_]
あなたはここでの問題を持っている、それがパフォーマンスの問題ではありません。特定の順序で配信される属性(対応するHEADER要素と同じ順序)に依存しており、それは安全ではありません。あなたは単に属性の順序に頼ることができないので、出力の順序を制御する他の方法を見つける必要があります。その問題を無視
は、私はあなたのコードがに削減思う:
<xsl:variable name="headers"
select='/Header/*[starts-with (text(), 'Car')] '/>
<xsl:for-each select="/data/row">
<xsl:variable name="thisRow" select="."/>
<xsl:for-each select='$headers'>
<xsl:variable name="COLUMN_"
select="count(./preceding-sibling::*) + 1"/>
<xsl:value-of select="$thisRow/@*[position()=$COLUMN_]"/>
<xsl:value-of select ="$Delimiter"/>
</xsl:for-each>
</xsl:for-each>
(変数名の末尾にアンダースコアの意義何不要な難読化のそのようなものは、私は本当にイライラを取得します...?)
あなたが 'position()'の代わりに 'count(./ preceding-sibling :: *)'を使っているからです。しかし、[mcve]がなければ、それは唯一の推測です。パフォーマンスはプロセッサ固有であることにも注意してください。 –