私の XSLT サガのこの章は、質問hereの延長です。ここまで助けてくれた皆さん (@Martin Honnen、@Ian Roberts、@Tim C、その他私が見逃した人) に感謝します!
これが私の現在の問題です:
- のいくつかの兄弟を並べ替えて、
A_v1.xml
を作成しますA_v2.xml
。 これら 2 つのファイルは、同じファイルの異なる「バージョン」であると考えています。 ファイル 2 つのファイルの内容はまったく同じですが、兄弟の順序が異なるだけです。別の言い方をすれば、 の各要素A_v2.xml
は の場合と同じ親を持っていA_v1.xml
ますが、以前は後に発生していた兄弟の前に発生するか、前に発生していた兄弟の後に発生する可能性があります。 - 私は変身
A_v1.xml
するA_v1_transformed.xml
- 私は変身
A_v2.xml
するA_v2_transformed.xml
- 私は、それらが同一ではないことに失望しています
A_v1_transformed.xml
。A_v2_transformed.xml
さらに、どちらも に示した予想どおりの順序ではありませんexpected.xml
。内容は同じですが、要素は同じ順序でソートされていません。
私の最初の並べ替えは<xsl:sort select="local-name()"/>
. @G. ケン・ホルマンは私をオンにしました<xsl:sort select="."/>
(これは私が使用していたものと同じ効果が<xsl:sort select="self::*"/>
あります)。これらの 2 つの並べ替えを組み合わせて使用すると、ほぼ正確に必要なものが得られますが、予想されるアルファベット順がランダムに壊れているように見える場所もあります。
サンプルファイルを強化しました。質問を短くするために、私はそれらをペーストビンに入れました。
これは、変換によってこれらのファイルが正しくソートされなかった場所/理由を理解できるように、私がコメントを追加した変換済みファイルの 1 つです。同様の「失敗」があるため、他の変換されたファイルについてはコメントしませんでした。
A_v1_transformed_with_comments.xml
変換されたドキュメントは両方とも と同じチェックサムを持つ必要がありますexpected.xml
が、そうではありません。 それが私の最大の関心事です。アルファベット順の並べ替えは並べ替えの最も適切な方法のようですが、変換が適切な方法で並べ替えられている限り、同じファイルの異なる「バージョン」間で並べ替えが繰り返される限り 、並べ替えがどのように行われたかはあまり気にしませんでした。
次の XLS ファイルはどちらも同じ結果になりますが、「マルチパス」バージョンの方が理解しやすい場合があります。
議論のポイント:
- アルファベット順に並べ替えると、大文字の文字が優先されることに気付きました。大文字がアルファベット順で小文字の後に来る場合でも、並べ替えでは最初になります。
部分的な成功...
私は自分で部分的な解決策に出くわしたかもしれないと思いますが、なぜそれが機能するのかは不明です。私のxsl_multi_pass.xsl
ファイルを見ると、次のように表示されます。
<!-- Third pass with sortElements mode templates -->
<xsl:variable name="sortElementsRslt">
<xsl:apply-templates mode="sortElements" select="$sortAttributesRslt"/>
</xsl:variable>
<!-- Fourth pass with deDup mode templates -->
<xsl:apply-templates mode="deDup" select="$sortElementsRslt"/>
それを次のようにすると:
<!-- Third pass with sortElements mode templates -->
<xsl:variable name="sortElementsRslt1">
<xsl:apply-templates mode="sortElements" select="$sortAttributesRslt"/>
</xsl:variable>
<!-- Fourth pass with sortElements mode templates -->
<xsl:variable name="sortElementsRslt2">
<xsl:apply-templates mode="sortElements" select="$sortElementsRslt1"/>
</xsl:variable>
<!-- Fifth pass with deDup mode templates -->
<xsl:apply-templates mode="deDup" select="$sortElementsRslt2"/>
これは要素を 2 回ソートします。なぜ必要なのかわかりません。私が提供したサンプルファイルを使用した結果は、私が期待したものから優先されるCAPITALIZED文字を差し引いたものですが、結果が一貫しているように見える限り、それは私を悩ませません. 問題は、この「解決策」によって、私が作業している実際のファイルの別の部分が矛盾してソートされることです。
成功!
私は最終的にこれを100%思い通りに機能させたと思います。ここで@Dimitre Novatchevが回答した関数を、属性名と値で要素に組み込みました。何らかの理由で、上記で説明したように、要素を並べ替えるには 2 つのパスを実行する (まったく同じテンプレートを 2 回適用する) 必要がありますが、20MB のファイルでさらに 3 秒かかるだけなので、あまり心配していません。
最終結果は次のとおりです。