Проблема группировки XSL
Использование XSLT 1.0 - у меня есть следующий XML, и я пытаюсь выполнить следующее
- Сгруппировать по первому полю, где id="1923", если атрибут значения совпадает
- и усреднить все поля с id="3095", используя атрибут значения
- и усреднить все поля с id="3095", используя атрибут значения
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Trans.xsl"?>
<Results>
<List count="6">
<Record contentId="1017835" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="1" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="3809" value="1" parentId="3809" parentName="5" ></Field>
<Field id="3096" type="4" valueID="3809" value="1" parentId="3809" parentName="5" ></Field>
</Record>
<Record contentId="1017828" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="2" parentRow="" >
<Field id="1923" type="1" value="Test 2"></Field>
<Field id="3095" type="4" valueID="729" value="2" parentId="729" parentName="2" ></Field>
<Field id="3096" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
</Record>
<Record contentId="1017978" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="3" parentRow="" >
<Field id="1923" type="1" value="Test 3"></Field>
<Field id="3095" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
<Field id="3096" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
</Record>
<Record contentId="1035463" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="4" parentRow="" >
<Field id="1923" type="1" value="Test 2"></Field>
<Field id="3095" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
<Field id="3096" type="4" valueID="730" value="3" parentId="730" parentName="3" ></Field>
</Record>
<Record contentId="1017985" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="5" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="113690" value="10" parentId="113690" parentName="10" ></Field>
<Field id="3096" type="4" valueID="113690" value="10" parentId="113690" parentName="10" ></Field>
</Record>
<Record contentId="1017835" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="6" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
<Field id="3096" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
</Record>
</List>
</Results>
Попытка произвести следующее, используя trans.xsl:
<Records>
<Data>
<Text1923>Test 1</Text1923>
<Avg3095>5.33</Avg3095>
<Avg3096>5.33</Avg3096>
</Data>
<Data>
<Text1923>Test 2</Text1923>
<Avg3095>3</Avg3095>
<Avg3096>4</Avg3096>
</Data>
<Data>
<Text1923>Test 3</Text1923>
<Avg3095>4</Avg3095>
<Avg3096>4</Avg3096>
</Data>
</Records>
1 ответ
Решение
Вот простое решение XSLT 1.0, использующее метод группирования по Мюнхену:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kFieldById" match="Field"
use="@id"/>
<xsl:key name="kField1923"
match="Field[@id='1923']" use="@value"/>
<xsl:template match="/">
<Records>
<xsl:for-each select=
"key('kFieldById', '1923')
[generate-id()
=
generate-id(key('kField1923',
@value
)
[1]
)
]
">
<Data>
<Text1923>
<xsl:value-of select="@value"/>
</Text1923>
<xsl:variable name="vSubfield3095" select=
"key('kField1923',@value)
/../Field[@id='3095']
"/>
<xsl:variable name="vSubfield3096" select=
"key('kField1923',@value)
/../Field[@id='3096']
"/>
<Avg3095>
<xsl:value-of select=
"sum($vSubfield3095/@value)
div
count($vSubfield3095)
"/>
</Avg3095>
<Avg3096>
<xsl:value-of select=
"sum($vSubfield3096/@value)
div
count($vSubfield3096)
"/>
</Avg3096>
</Data>
</xsl:for-each>
</Records>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к предоставленному XML-документу, получается требуемый, правильный результат:
<Records>
<Data>
<Text1923>Test 1</Text1923>
<Avg3095>5.333333333333333</Avg3095>
<Avg3096>5.333333333333333</Avg3096>
</Data>
<Data>
<Text1923>Test 2</Text1923>
<Avg3095>3</Avg3095>
<Avg3096>4</Avg3096>
</Data>
<Data>
<Text1923>Test 3</Text1923>
<Avg3095>4</Avg3095>
<Avg3096>4</Avg3096>
</Data>
</Records>