Я ненавижу даже спрашивать об этом, поскольку существует множество примеров, касающихся функциональности xsl: sort, однако я следовал им и до сих пор, по необъяснимым причинам, застрял.
У меня есть сортировка для каждого, как кажется требованием. Затем я хочу взять все отсортированные данные и применить шаблон.
Вот пример XML. У меня есть группа элементов журнала и элементов результата по отдельным путям, которые мне нужно отсортировать вместе на основе числового значения метки времени. В этом примере все уже отсортировано естественным образом, за исключением последнего элемента, значение числовой метки времени которого больше трех элементов результата, что означает, что он должен отображаться последним в выходных данных. Как написано, выходные данные будут отображать все элементы журнала, за которыми следуют все элементы результата в порядке их появления во входном XML.
<output>
<logs>
<log logtext="Username = " loglevel="DEBUG" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428014" />
<log logtext="Password = " loglevel="DEBUG" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428027" />
<log logtext="ServerURI = " loglevel="DEBUG" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428042" />
<log logtext="TRACE TEST" loglevel="TRACE" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428084" />
<log logtext="DEBUG TEST" loglevel="DEBUG" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428096" />
<log logtext="INFO TEST" loglevel="INFO" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428109" />
<log logtext="WARNING TEST" loglevel="WARN" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428120" />
<log logtext="ERROR TEST" loglevel="ERROR" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428133" />
<log logtext="Post-Result INFO Test" loglevel="INFO" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428353" />
</logs>
<results>
<result name="Passed Test" resultformat="TEXT" resulttype="PASS" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428352" />
<result name="Failed Test" resultformat="TEXT" resulttype="FAIL" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428352" />
<result name="Running Processes" resultformat="TABLE" resulttype="NONE" timestamp="1/23/2012 5:04:28 PM" numerictimestamp="20120123170428352">
</result>
</results>
</output>
Вот соответствующие части XSL:
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="//logs/log | //results/result">
<xsl:sort data-type="number" select="@numerictimestamp"/>
<xsl:apply-templates select="self::node()" />
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="log">
.... handle formatting of the log elements
</xsl:template>
<xsl:template match="result">
.... handle formatting of the result elements
</xsl:template>
Полагаю, это проблема области действия, так как сортировка применяется только к одному элементу в for-each, но я не уверен, что изменить, чтобы разрешить его и достичь того же результата. За исключением сортировки, этот XSL дает мне именно тот результат, который мне нужен.
EDIT1:
Обновление вопроса с включением измененного рабочего кода, включающего ответы и комментарии ниже. Сортировка не удалась из-за того, что сортируемые числа были слишком большими. Это значения меток времени, которые включают в себя миллисекунды, в частности, чтобы быть точными, поэтому иронично, что именно точность была причиной проблемы. Тем не менее, даже с более короткими числами, помещающими сортировку в для каждого, фактически не сортировалось больше чем один элемент.
Большинство примеров использования xsl: sort делают это в for-each. Я не знал, что вы можете включить его в шаблоны применения.
Следующая модификация работает правильно: (Обратите внимание, что я явно указал тип данных в качестве текста для ясности, я понимаю, что это по умолчанию)
<xsl:apply-templates select="//logs/log | //results/result">
<!--The data-type value for the sort MUST be text, due to rounding errors introduced
attempting to sort the numerictimestamp-->
<xsl:sort data-type="text" select="@numerictimestamp"/>
</xsl:apply-templates>
Мне удалось сохранить остальную часть XSL без изменений.