Сортировка не выполняется при использовании XSLT 1.0 Muenchian Grouping для создания вывода HTML

У меня есть следующий XML:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="Test.xslt"?>
<test-results>
    <test-case name="TestCase1" description="Descriptiontext">
        <categories>
            <category name="Dimension linked to measure group" />
        </categories>
    </test-case>
    <test-case name="TestCase2" description="DescriptionText">
        <categories>
            <category name="Dimension linked to measure group" />
        </categories>
    </test-case>
    <test-case name="TestCase3" description="DescriptionText">
        <categories>
            <category name="Default parameters" />
        </categories>
    </test-case>
    <test-case name="TestCase4" description="DescriptionText">
        <categories>
            <category name="Default parameters" />
        </categories>
    </test-case>
    <test-case name="TestCase5" description="DescriptionText">
        <categories>
            <category name="Referential Integrity" />
        </categories>
        <reason>
            <message><![CDATA[Not testable, yet (v1.6.1)]]></message>
        </reason>
    </test-case>
    <test-case name="TestCase6" description="DescriptionText">
        <categories>
            <category name="Referential Integrity" />
        </categories>
        <reason>
            <message><![CDATA[Not testable, yet (v1.6.1)]]></message>
        </reason>
    </test-case>
</test-results>

В следующем XSLT я пытаюсь использовать мюнхианскую группировку для упорядочения по имени категории (по возрастанию) и внутри каждой категории по имени тестового примера (по возрастанию).

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml">
    <xsl:key name="cases-by-category" match="categories" use="category/@name" />
    <xsl:template match="test-case">
        <xsl:for-each select="categories[count(. | key('cases-by-category', category/@name)[1]) = 1]">
            <xsl:sort select="category/@name" />
            <xsl:value-of select="category/@name" /><br/>
            <xsl:for-each select="key('cases-by-category', category/@name)">
                <xsl:sort select="//test-case/@name" />
                <xsl:value-of select="//test-case/@name"/><br/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Однако я получаю следующее:

Dimension linked to measure group
TestCase1
TestCase1
Default parameters
TestCase1
TestCase1
Referential Integrity
TestCase1
TestCase1

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


person thuss    schedule 14.08.2014    source источник


Ответы (1)


Учитывая <xsl:key name="cases-by-category" match="categories" use="category/@name" />, выражение key('cases-by-category', category/@name) дает вам набор узлов из categories элементов, если вы хотите отсортировать их по родителю, я думаю, вы хотите использовать <xsl:sort select="../@name" />.

я тоже думаю иметь

<xsl:template match="test-case">
    <xsl:for-each select="categories[count(. | key('cases-by-category', category/@name)[1]) = 1]">

выглядит странно, поскольку вы обрабатываете категории каждого совпадающего элемента test-case, скорее всего, вы хотите

<xsl:template match="test-results">
    <xsl:for-each select="test-case/categories[count(. | key('cases-by-category', category/@name)[1]) = 1]">

вместо.

Вот полный образец:

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

    <xsl:output indent="yes"/>

    <xsl:key name="cases-by-category" match="categories" use="category/@name" />

    <xsl:template match="/">
      <html>
        <body>
          <xsl:apply-templates/>
        </body>
      </html>
    </xsl:template>

    <xsl:template match="test-results">
      <xsl:for-each select="test-case/categories[count(. | key('cases-by-category', category/@name)[1]) = 1]">
            <xsl:sort select="category/@name" />
            <xsl:value-of select="category/@name" /><br/>
            <xsl:for-each select="key('cases-by-category', category/@name)">
                <xsl:sort select="../@name" />
                <xsl:value-of select="../@name"/><br/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Когда я запускаю это с Saxon 6.5 против вашего ввода, я получаю следующий результат:

<html xmlns="http://www.w3.org/1999/xhtml">
   <body>Default parameters<br/>TestCase3<br/>TestCase4<br/>Dimension linked to measure group<br/>TestCase1<br/>TestCase2<br/>Referential Integrity<br/>TestCase5<br/>TestCase6<br/>
   </body>
</html>
person Martin Honnen    schedule 14.08.2014
comment
Подсказка к ../@name вместо test-case/@name сработала очаровательно, подставив ее как в теги sort, так и в теги value-of, все имена тестовых случаев будут отображаться правильно в алфавитном порядке. Однако использование тестовых результатов приводит к тому, что вообще ничего не отображается. Единственное, что меня смущает, это сортировка по категориям (первой сортировки). На данный момент я делаю это точно так же, как и второй (теперь работающий), но команда сортировки, похоже, игнорируется... - person thuss; 14.08.2014
comment
Я все еще думаю, что мое второе предложение жизненно важно для получения желаемой группировки и сортировки. - person Martin Honnen; 15.08.2014
comment
Очень может быть, я дам ему еще раз назад, когда я доберусь до него. Если я смогу как-то заставить его работать, я обязательно оставлю комментарий. Но пока спасибо, Мартин! - person thuss; 15.08.2014
comment
@thuss, я включил полный образец XSLT с предложениями, которые я сделал, и результатом, который я получил. - person Martin Honnen; 15.08.2014
comment
Работает нормально, правда. Спасибо. - person thuss; 18.08.2014