Группировка узлов по значениям узлов жесткого кодирования в XSLT
<root>
<Entry>
<ID>1</ID>
<Details>
<Code>A1</Code>
<Value>1000</Value>
</Details>
</Entry>
<Entry>
<ID>2</ID>
<Details>
<Code>A2</Code>
<Value>2000</Value>
</Details>
</Entry>
<Entry>
<ID>3</ID>
<Details>
<Code>B1</Code>
<Value>3000</Value>
</Details>
</Entry>
<Entry>
<ID>4</ID>
<Details>
<Code>B2</Code>
<Value>4000</Value>
</Details>
</Entry>
</root>
У меня есть этот входной XML, который я хочу сгруппировать с помощью XSLT, в котором группировка происходит путем жесткого кодирования значений узлов. Позвольте мне объяснить это подробно:
Группировка должна происходить на основе параметра кода, отображаемого в узле.
<Code>
следующим образом:
- Коды "A1" и "A2" необходимо сгруппировать вместе.
- Коды "B1" и "B2" необходимо сгруппировать вместе.
В конце концов я суммирую значения, полученные из
<Value>
узлы в этих группах. Таким образом, результат будет следующим:
<Output>
<Code-group> A </Code-group>
<Sum> 3000 </Sum>
<Code-group> B </Code-group>
<Sum> 7000 </Sum>
</Output>
Для этого требования необходимо жесткое кодирование значений группировки (для групп A1,A2 как A и B1, B2 как B). Я использую слово "жестко запрограммировано", потому что коды (A1,A2,B1,B2) могут идти в любом порядке, поэтому я хочу скорее жестко закодировать значения для поиска группировки, чем для поиска индексов узлов.
Я рассмотрел метод для каждой группы, а также метод группировки Мюнчи, но не смог достичь указанного выше сопоставления групп. Любая помощь приветствуется!
заранее спасибо
РЕДАКТИРОВАТЬ: отображение A1,A2 -> A & B1,B2 -> B является общим примером, фактические значения узлов полностью отличаются от этого, поэтому решение для подстроки не будет работать. Вот почему я сосредоточился на жестком кодировании для достижения этого сопоставления.
2 ответа
Требование жесткого кодирования сложно понять. Возможно, вы захотите сделать что-то вроде:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="entry" match="Entry" use="Details/Code"/>
<xsl:template match="/root">
<Output>
<Code-group> A </Code-group>
<Sum>
<xsl:value-of select="sum(key('entry', ('A1', 'A2'))/Details/Value)" />
</Sum>
<Code-group> B </Code-group>
<Sum>
<xsl:value-of select="sum(key('entry', ('B1', 'B2'))/Details/Value)" />
</Sum>
</Output>
</xsl:template>
</xsl:stylesheet>
Если у вас есть возможность использовать для каждой группы, я бы определенно использовал это вместо группировки Мюнчи...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<Output>
<xsl:for-each-group select="Entry" group-by="substring(Details/Code,1,1)">
<Code-group>
<xsl:value-of select="current-grouping-key()"/>
</Code-group>
<Sum>
<xsl:value-of select="sum(current-group()/Details/Value)"/>
</Sum>
</xsl:for-each-group>
</Output>
</xsl:template>
</xsl:stylesheet>
Скрипка: http://xsltfiddle.liberty-development.net/jxNakzX
Если вы действительно хотите жестко закодировать отображение "A" -> A1, A2 и "B" -> B1, B2, вы можете использовать xsl:key, а не группировать вообще...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="A" match="Entry[Details/Code=('A1','A2')]" use="'A'"/>
<xsl:key name="B" match="Entry[Details/Code=('B1','B2')]" use="'B'"/>
<xsl:template match="/*">
<xsl:variable name="ctx" select="."/>
<Output>
<xsl:for-each select="('A','B')">
<xsl:variable name="key" select="."/>
<Code-group>
<xsl:value-of select="$key"/>
</Code-group>
<Sum>
<xsl:value-of select="sum($ctx/key($key,$key)/Details/Value)"/>
</Sum>
</xsl:for-each>
</Output>
</xsl:template>
</xsl:stylesheet>
Скрипка: http://xsltfiddle.liberty-development.net/jxNakzX/1