XSLT 2.0 — группировка высокого уровня с помощью сумм (WordML)

Уважаемые профессионалы,

У меня есть совместный XML-код для выставления счетов, в котором есть сводки Time Card/Timekeeper. Я могу легко сгруппировать по конкретному делу, затем по хронометристу и получить итоги по делу. Но мне нужно получить сумму всех часов и выставленных счетов хронометристом для всего совместного счета, а не только по делу.

У меня есть весь код, указанный ниже, но обновленный из комментария @Tim-C. Ссылка XSL Transform находится ЗДЕСЬ

ВВОД:

<?xml version="1.0" encoding="utf-8"?>
<superbill>
    <invoice type="P" id="562845" number="562845">
        <matters>
            <matter number="014592-000007">
                <timecard-summary-by-timekeeper>
                    <timekeeper-summary timekeeper-id="NC1">
                        <timekeeper>
                            <initials>NC1</initials>
                            <billingname>Nicholas J. Collins</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">525.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                    <timekeeper-summary timekeeper-id="BJB">
                        <timekeeper>
                            <initials>BJB</initials>
                            <billingname>Billie J. Bob</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">575.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                </timecard-summary-by-timekeeper>
            </matter>
            <matter number="014592-000091">
                <timecard-summary-by-timekeeper>
                    <timekeeper-summary timekeeper-id="NC1">
                        <timekeeper>
                            <initials>NC1</initials>
                            <billingname>Nicholas J. Collins</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">525.00</total>
                                <total type="hours">1.00</total>
                                <total type="amount">525.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">525.00</total>
                                <total type="hours">1.00</total>
                                <total type="amount">525.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">525.00</total>
                                <total type="hours">1.00</total>
                                <total type="amount">525.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">525.00</total>
                                <total type="hours">1.00</total>
                                <total type="amount">525.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">1.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                    <timekeeper-summary timekeeper-id="BJB">
                        <timekeeper>
                            <initials>BJB</initials>
                            <billingname>Billie J. Bob</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">575.00</total>
                                <total type="hours">11.00</total>
                                <total type="amount">6325.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">575.00</total>
                                <total type="hours">11.00</total>
                                <total type="amount">6325.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">575.00</total>
                                <total type="hours">11.00</total>
                                <total type="amount">6325.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">575.00</total>
                                <total type="hours">11.00</total>
                                <total type="amount">6325.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">11.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                </timecard-summary-by-timekeeper>
            </matter>
            <matter number="014592-000092">
                <timecard-summary-by-timekeeper>
                    <timekeeper-summary timekeeper-id="NC1">
                        <timekeeper>
                            <initials>NC1</initials>
                            <billingname>Nicholas J. Collins</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">525.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                    <timekeeper-summary timekeeper-id="BJB">
                        <timekeeper>
                            <initials>BJB</initials>
                            <billingname>Billie J. Bob</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">575.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                </timecard-summary-by-timekeeper>
            </matter> 
            <matter number="014592-000095">
                <timecard-summary-by-timekeeper>
                    <timekeeper-summary timekeeper-id="NC1">
                        <timekeeper>
                            <initials>NC1</initials>
                            <billingname>Nicholas J. Collins</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">525.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2100.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">525.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2100.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">525.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2100.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">525.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2100.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                    <timekeeper-summary timekeeper-id="BJB">
                        <timekeeper>
                            <initials>BJB</initials>
                            <billingname>Billie J. Bob</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">575.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">0.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                </timecard-summary-by-timekeeper>
            </matter>
            <matter number="014592-000096">
                <timecard-summary-by-timekeeper>
                    <timekeeper-summary timekeeper-id="NC1">
                        <timekeeper>
                            <initials>NC1</initials>
                            <billingname>Nicholas J. Collins</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">525.00</total>
                                <total type="hours">20.00</total>
                                <total type="amount">10500.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">525.00</total>
                                <total type="hours">20.00</total>
                                <total type="amount">10500.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">525.00</total>
                                <total type="hours">20.00</total>
                                <total type="amount">10500.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">525.00</total>
                                <total type="hours">20.00</total>
                                <total type="amount">10500.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">20.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                    <timekeeper-summary timekeeper-id="BJB">
                        <timekeeper>
                            <initials>BJB</initials>
                            <billingname>Billie J. Bob</billingname>
                        </timekeeper>
                        <timekeeper-summary-totals>
                            <timekeeper-summary-total type="billed">
                                <total type="rate">575.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2300.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="worked">
                                <total type="rate">575.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2300.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="standard">
                                <total type="rate">575.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2300.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate1">
                                <total type="rate">575.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">2300.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                            <timekeeper-summary-total type="timerate2">
                                <total type="rate">0.00</total>
                                <total type="hours">4.00</total>
                                <total type="amount">0.00</total>
                                <total type="adjustment">0.00</total>
                            </timekeeper-summary-total>
                        </timekeeper-summary-totals>
                    </timekeeper-summary>
                </timecard-summary-by-timekeeper>
            </matter>
        </matters>
    </invoice>
</superbill>

ТЕКУЩИЙ КОД:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
               xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" 
                version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <xsl:call-template name="XJ_TKSummary_02" />
    </xsl:template>

    <xsl:template name="XJ_TKSummary_02">
       <xsl:variable name="TW" select="1440" />
        <xsl:for-each-group select="//superbill/invoice/matters/matter/timecard-summary-by-timekeeper/timekeeper-summary/timekeeper" group-by="../@timekeeper-id">
            <w:p>
                <w:r>
                    <w:t><xsl:value-of select="initials" /> - <xsl:value-of select="billingname" /></w:t>
                </w:r>
            </w:p>
            <w:p>
                <w:r>
                    <xsl:variable name="groupTotals" select="current-group()/timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total" />
                    <w:t>
                        Hours: <xsl:value-of select="format-number(sum($groupTotals[@type='hours']), '###,##0.00')" />
                        for $ <xsl:value-of select="format-number(sum($groupTotals[@type='amount']), '###,##0.00')" />
                    </w:t>
                </w:r>
            </w:p>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

ВЫВОД:

Желаемые итоги должны читаться...

NC1 - Nicholas J. Collins
Hours: 25.00 for $13,125.00

BJB - Billie J. Bob
Hours: 15.00 for $8,625.00

Любая помощь будет оценена по достоинству.

Внимание,

-Ник


person NCollinsTE    schedule 25.05.2017    source источник


Ответы (1)


Главное, что вам нужно сделать, это изменить xsl:for-each-group на это...

<xsl:for-each-group select="//invoice/matter/timecard-summary-by-timekeeper/timekeeper-summary/timekeeper" group-by="../@timekeeper-id">

Итак, вы группируете записи timekeeper по их родительскому атрибуту timekeeper-id.

Вам также необходимо включить timekeeper-summary-totals в xpath, чтобы получить общее количество часов и сумму.

<w:t>
  Hours: 
 <xsl:value-of select="format-number(sum(current-group()/timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total[@type='hours']), '###,##0.00')" />
 for $
 <xsl:value-of select="format-number(sum(current-group()/timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total[@type='amount']), '###,##0.00')" />
</w:t>

Или, что еще лучше, используйте переменную, чтобы сократить повторение кода xpath.

Попробуйте этот сокращенный XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
               xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" 
                version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <xsl:call-template name="XJ_TKSummary_02" />
    </xsl:template>

    <xsl:template name="XJ_TKSummary_02">
       <xsl:variable name="TW" select="1440" />
        <xsl:for-each-group select="//invoice/matter/timecard-summary-by-timekeeper/timekeeper-summary/timekeeper" group-by="../@timekeeper-id">
            <w:p>
                <w:r>
                    <w:t><xsl:value-of select="initials" /> - <xsl:value-of select="billingname" /></w:t>
                </w:r>
            </w:p>
            <w:p>
                <w:r>
                    <xsl:variable name="groupTotals" select="current-group()/timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total" />
                    <w:t>
                        Hours: <xsl:value-of select="format-number(sum($groupTotals[@type='hours']), '###,##0.00')" />
                        for $ <xsl:value-of select="format-number(sum($groupTotals[@type='amount']), '###,##0.00')" />
                    </w:t>
                </w:r>
            </w:p>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>
person Tim C    schedule 25.05.2017
comment
Благодарю вас! Я получаю каждого отдельного хронометриста, но получаю 0,00 как за часы, так и за количество. - person NCollinsTE; 25.05.2017
comment
Только что заметил, что он принимает во внимание только первый вопрос. Только что проверил добавление 4-го и 5-го хронометриста во 2-е дело в XML, и он перечисляет только 3 исходных хронометриста, а не суммирует #. Что-то удерживает их на уровне 0.00. - person NCollinsTE; 25.05.2017
comment
@NCollinsTE, подумайте о том, чтобы отредактировать свой вопрос и предоставить минимальный образец ввода с полным байтом, чтобы продемонстрировать проблему. Когда я пытаюсь использовать ваш текущий фрагмент кода и код Тима на xsltransform.net/a9GiwC, похоже, выводятся значения, которые вы описали пока. - person Martin Honnen; 25.05.2017
comment
@ martin-honnen - таким же образом я создал фрагмент с полной урезанной версией моего XML-файла (удалив все данные клиента / юридической фирмы из файла, изменив имена адвокатов и оставив информацию о табеле учета рабочего времени). Я все еще получаю 0,00 часов и 0,00 долларов США за сумму. Первый хронометрист должен показывать 25 часов по цене 13 125 долларов США, а второй должен показывать 15 часов по цене 8 625 долларов США. - person NCollinsTE; 25.05.2017
comment
@NCollinsTE, вам нужно будет отредактировать свой вопрос и поделиться подробностями, чтобы мы могли сообщить, что пошло не так. - person Martin Honnen; 25.05.2017
comment
@martin-honnen Готово. - person NCollinsTE; 25.05.2017
comment
В этом примере структура немного отличается, поэтому я думаю, что вы хотите изменить <xsl:variable name="groupTotals" select="current-group()/timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total" /> на <xsl:variable name="groupTotals" select="current-group()/../timekeeper-summary-totals/timekeeper-summary-total[@type='billed']/total" /> - person Martin Honnen; 25.05.2017
comment
В качестве альтернативы вы можете адаптировать группировку, как я сделал в xsltransform.net/3MvmrzE/2. с напр. <xsl:for-each-group select="//superbill/invoice/matters/matter/timecard-summary-by-timekeeper/timekeeper-summary" group-by="@timekeeper-id"> - person Martin Honnen; 25.05.2017