我的 XSLT 传奇中的这一章是这里问题的扩展。感谢所有帮助我走到这一步的人(@Martin Honnen、@Ian Roberts、@Tim C 以及我想念的任何其他人)!
这是我目前的问题:
- 我将一些兄弟姐妹重新排序
A_v1.xml
以创建A_v2.xml
. 我现在认为这两个文件是同一文件的不同“版本”。 文件 两个文件具有完全相同的内容,只是一些同级文件的顺序不同。换一种说法,in 中的每个元素A_v2.xml
仍然具有与 in 相同的父元素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。肯·霍尔曼(Ken Holman)把我变成了<xsl:sort select="."/>
(这与我使用的效果相同<xsl:sort select="self::*"/>
)。当我结合使用这两种类型时,我几乎得到了我想要的东西,但在某些地方,预期的字母顺序似乎只是随机破坏。
我已经加强了我的示例文件。为了使问题简短,我只是将它们放在pastebin上。
这是我添加的带有注释的转换文件之一,可帮助您了解我认为转换对这些文件进行错误排序的位置/原因。我没有评论其他转换后的文件,因为它有类似的“失败”。
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"/>
这对元素进行了两次排序,我不知道为什么有必要。使用我提供的示例文件的结果是我所期望的减去优先使用大写字母的结果,但只要结果与它看起来一致,这不会打扰我。问题是这个“解决方案”导致我正在使用的真实文件的另一部分排序不一致。
成功!
我想我终于得到了我想要的 100% 的工作。我通过属性名称和值将@Dimitre Novatchev在此处的答案中给出的函数合并到元素中。由于某种原因,我仍然需要执行两次传递来对元素进行排序(两次应用完全相同的模板),但是对于 20MB 的文件只需要额外的 3 秒,所以我不太担心。
这是最终结果: