В настоящее время я работаю над сложным преобразованием, в котором мне нужно суммировать сумму стоимости игровых статей, когда статья появляется дважды, и исключать вторую статью из вывода.
Пояснение: У каждой статьи есть идентификатор, название, цена и номер копии. В моем случае у меня всегда есть две копии. Копия 0 и Копия 1. Если статья имеет две копии, то мы добавляем цену копии статьи 1 в копию статьи 0 и исключаем копию 1 из вывода.
Я не совсем уверен, как подойти к этому требованию.
XML-вход
<?xml version = "1.0" encoding = "UTF-8"?>
<wd:Report_Data>
<wd:Report_Entry>
<wd:id>1000</wd:id>
<wd:name>Call of Duty</wd:name>
<wd:price>50.12</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:id>1000</wd:id>
<wd:name>Call of Duty</wd:name>
<wd:price>60.0</wd:price>
<wd:copy>1</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:id>2000</wd:id>
<wd:name>Metal Slug</wd:name>
<wd:price>75.00</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:id>3000</wd:id>
<wd:name>Need For Speed</wd:name>
<wd:price>40.00</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
</wd:Report_Data>
Ожидаемый вывод XML:
<?xml version = "1.0" encoding = "UTF-8"?>
<wd:Report_Data>
<wd:Report_Entry>
<wd:id>1000</wd:id>
<wd:name>Call of Duty</wd:name>
<wd:price>110.12</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:id>2000</wd:id>
<wd:name>Metal Slug</wd:name>
<wd:price>75.00</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:id>3000</wd:id>
<wd:name>Need For Speed</wd:name>
<wd:price>40.00</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
</wd:Report_Data>
Следуя рекомендации @michael.hor257k, мне удалось создать структуру группировки и просуммировать цену. Однако ожидаемого результата я так и не получил
XSLT
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "2.0" xmlns:wd = "http://www.workday.org/" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:xs = "http://www.w3.org/2001/XMLSchema">
<xsl:template match = "/">
<xsl:for-each-group select = "wd:Report_Data/wd:Report_Entry" group-by = "wd:id">
<xsl:copy>
<xsl:copy-of select = "wd:id"/>
<xsl:copy-of select = "wd:name"/>
<wd:price>
<xsl:value-of select = "sum(current-group()/wd:price)" />
</wd:price>
<xsl:copy-of select = "wd:copy"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
Результат (не тот, что я хочу)
<wd:Report_Entry xmlns:wd = "http://www.workday.org/">
<wd:id>1000</wd:id>
<wd:name>Call of Duty</wd:name>
<wd:price xmlns:xs = "http://www.w3.org/2001/XMLSchema">110.12</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry xmlns:wd = "http://www.workday.org/">
<wd:id>2000</wd:id>
<wd:name>Metal Slug</wd:name>
<wd:price xmlns:xs = "http://www.w3.org/2001/XMLSchema">75</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
<wd:Report_Entry xmlns:wd = "http://www.workday.org/">
<wd:id>3000</wd:id>
<wd:name>Need For Speed</wd:name>
<wd:price xmlns:xs = "http://www.w3.org/2001/XMLSchema">40</wd:price>
<wd:copy>0</wd:copy>
</wd:Report_Entry>
Идеальный. я попробую
@michael.hor257k – Не могли бы вы меня немного подсказать? Я понимаю использование таких функций группировки, как (для каждого и для каждой группы). Однако я не понимаю, как построить механизм, который суммирует только в статье (с копией = 0).
Я не понимаю сложности: просто сгруппируйте записи по их идентификаторам и просуммируйте цены группы. Группа из 1 — это такая же группа, как и любая другая.
Вот пример, который вы можете использовать в качестве отправной точки: stackoverflow.com/a/39185213/3016153
@michael.hor257k — Мой вывод в формате XML выглядит неправильно. Я предполагаю, что проблема связана с выбранным мной путем сопоставления. Я пробовал несколько комбинаций, но безрезультатно
Вам нужно лишь внести несколько небольших изменений:
<xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:wd = "http://www.workday.org/">
<xsl:output method = "xml" indent = "yes"/>
<xsl:template match = "/wd:Report_Data">
<xsl:copy>
<xsl:for-each-group select = "wd:Report_Entry" group-by = "wd:id">
<xsl:copy>
<xsl:copy-of select = "wd:id"/>
<xsl:copy-of select = "wd:name"/>
<wd:price>
<xsl:value-of select = "sum(current-group()/wd:price)" />
</wd:price>
<xsl:copy-of select = "wd:copy"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
В этом нет ничего «хитрого»; это основная проблема группировки. Выполните поиск — это, вероятно, наиболее часто задаваемый здесь вопрос о XSLT. Обратите внимание, что ответы различаются для XSLT 1.0 или 2.0 и выше.