Выбор произвольного родного брата для каждого - PullRequest
1 голос
/ 03 декабря 2011

Я перебираю коллекцию узлов, каждый с двумя элементами, и хочу вывести таблицу из двух столбцов для каждой группы.Таблица отсортирована в алфавитном порядке, вниз по первому столбцу, затем по второму столбцу.Я группирую по первому элементу, затем выводю каждый второй элемент в двух столбцах.

Пример источника данных:

<ArrayOfEIS_CT_AssignmentByRegion
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <EIS_CT_AssignmentByRegion>
        <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>            
        <CountryName>IRAQ</CountryName>            
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
        <CountryName>JORDAN</CountryName>
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
        <CountryName>GAZA AND WEST BANK</CountryName>
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
        <CountryName>KUWAIT</CountryName>
    </EIS_CT_AssignmentByRegion>    
    <EIS_CT_AssignmentByRegion>
        <Region>SUBSAHARAN AFRICA</Region>
        <CountryName>TOGO</CountryName>
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>SUBSAHARAN AFRICA</Region>
        <CountryName>ZIMBABWE</CountryName>
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>SUBSAHARAN AFRICA</Region>
        <CountryName>ZAMBIA</CountryName>
    </EIS_CT_AssignmentByRegion>
    <EIS_CT_AssignmentByRegion>
        <Region>SUBSAHARAN AFRICA</Region>
        <CountryName>UGANDA</CountryName>
    </EIS_CT_AssignmentByRegion>
</ArrayOfEIS_CT_AssignmentByRegion>

XSLT:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:w="http://schemas.microsoft.com/office/word/2006/wordml">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>    
    <xsl:key name="list-by-region" match="EIS_CT_AssignmentByRegion" use="concat(generate-id(..), '|', Region)"/>
    <xsl:template match="/ArrayOfEIS_CT_AssignmentByRegion">
        <html>
            <body>
                <xsl:for-each select="EIS_CT_AssignmentByRegion[generate-id() = generate-id(key('list-by-region', concat(generate-id(..), '|', Region))[1])]">                    
                    <xsl:sort select="Region" />
                    <xsl:sort select="CountryName" />
                    <xsl:variable name="halfIndex" select="floor(count(key('list-by-region', concat(generate-id(..), '|', Region))) div 2)" />
                    <table>
                        <thead>
                            <tr>
                                <th colspan="2">
                                    <xsl:value-of select="Region" />
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            <xsl:for-each select="key('list-by-region', concat(generate-id(..), '|', Region))">
                                <xsl:sort select="CountryName" />
                                <xsl:variable name="countryColumn2" select="following-sibling::*[position() = $halfIndex]" />
                                <xsl:if test="position() &lt;= $halfIndex">
                                    <tr>
                                        <td>
                                            <xsl:value-of select="CountryName" />
                                        </td>
                                        <td>
                                            <xsl:value-of select="$countryColumn2" />
                                        </td>
                                    </tr>
                                </xsl:if>
                            </xsl:for-each>
                        </tbody>
                    </table>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

вывод, который я хочу получить:

    <html>
    <body>
    <table>
        <thead>
            <tr>
                <th colspan="2">
                    MIDDLE EAST, NORTH AFRICA and EUROPE
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    GAZA AND WEST BANK
                </td>
                <td>
                    JORDAN
                </td>
            </tr>
            <tr>
                <td>
                    IRAQ
                </td>
                <td>
                    KUWAIT
                </td>
            </tr>
        </tbody>
    </table>
    <table>
        <thead>
            <tr>
                <th colspan="2">
                    SUBSAHARAN AFRICA
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    TOGO
                </td>
                <td>
                    ZAMBIA
                </td>
            </tr>
            <tr>
                <td>
                    UGANDA
                </td>
                <td>
                    ZIMBABWE
                </td>
            </tr>
        </tbody>
    </table>
    </body>
</html>

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

Для тестирования я выполнил прогон с выводом всех стран по порядку, в один столбец, и они были сгруппированы и отсортированы правильно.Таким образом, эта строка

<xsl:variable name="countryColumn2" 
     select="following-sibling::*[position() = $halfIndex]" />

для некоторых групп оставляет текущий контекст для выбора узла-брата.Есть идеи?Спасибо.

1 Ответ

1 голос
/ 03 декабря 2011
<xsl:variable name="countryColumn2"       
  select="following-sibling::*[position() = $halfIndex]" /> 

для некоторых групп оставляет текущий контекст для выбора узла-брата.Любые идеи?

Хороший вопрос, + 1.

Сортировка с <xsl:sort> не меняет исходные родственные отношения между узлами в документе XML.

Следовательно, для двух узлов: node1 и его последующего брата node2,, хотя node1 следует после node2 в результате сортировки, все еще верно, что node2 является следующим братомnode1.

Решение :

  1. Pass1 : вывести результат сортировки во временное дерево ив этом дереве родственные отношения между узлами точно отражают порядок их сортировки.

  2. Pass2 : продолжить обработку во втором проходе по результату первого прохода.Теперь вы можете использовать родственные оси по назначению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...