Почему этот xsl: селектор сортировки не работает?

#xml #xslt

#xml #xslt

Вопрос:

Учитывая следующий XML:

 <?xml version="1.0"?>
<Things>
  <Thing>
    <Thing ID="0002"/>
    <Name>Bob</Name>
  </Thing>
  <Thing>
    <Thing ID="0003"/>
    <Name>Alice</Name>
  </Thing>
  <Thing>
    <Thing ID="0001"/>
    <Name>Carol</Name>
  </Thing>
</Things>
  

Я хочу вывести тот же XML, отсортирован по атрибуту ID. Следующая таблица стилей делает то, что я хочу. Закомментированный xsl:sort (и несколько вариантов, которые я пробовал) не работает — Я просто получаю несортированную копию исходного документа. (И никаких сообщений об ошибках.)

Как я могу конкретно выбрать атрибут ID для элемента Thing (чтобы избежать использования атрибутов ID для других элементов, которые могут присутствовать в документе большего размера)?

 <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

 <xsl:template match="node()|@*">
   <xsl:copy>
     <xsl:apply-templates select="node()|@*" />
   </xsl:copy>
 </xsl:template>

 <xsl:template match="Things">
   <xsl:copy>
     <xsl:apply-templates>
       <xsl:sort select="*/@ID" data-type="number"/>

       <!-- I don't understand why this doesn't work:

         <xsl:sort select="Thing/Thing[@ID]" data-type="number"/>
       -->
     </xsl:apply-templates>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>
  

Ответ №1:

Вы хотите

     <xsl:sort select="Thing/@ID" data-type="number"/>
  

В момент, когда это происходит, контекст уже находится на каждом первом уровне Thing , поэтому ключом сортировки является атрибут @ID объекта второго уровня.

Комментарии:

1. 1 за правильный ответ. Чтобы объяснить подробнее, @bst, разница между Thing/@ID и Thing[@ID] заключается в том, что первое означает » ID атрибут Thing элемента», в то время как второе означает » Thing элемент, у которого есть ID атрибут» (замалчивая некоторые мелкие детали для простоты).