Эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElementByName" match="*/*" use="name()"/>
<xsl:variable name="vFields"
select="//*/*[count(.|key('kElementByName',name())[1])=1]"/>
<xsl:template match="/*/*">
<xsl:variable name="vCurrent" select="."/>
<xsl:for-each select="$vFields">
<xsl:variable name="vField"
select="$vCurrent/descendant-or-self::*[
name() = name(current())
]"/>
<xsl:variable name="vValue"
select="($vField/@titel|$vField/text())[last()]"/>
<xsl:if test="position()!=1">,</xsl:if>
<xsl:value-of
select="concat(substring('	',1 div not($vValue)),$vValue)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Вывод:
car,volvo,red
car,volvo,green
car,ford,red
bike,trek,blue
РЕДАКТИРОВАТЬ : Группировка по запросу, эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kTypeByTitel" match="type" use="@titel"/>
<xsl:key name="kBrandByType-Titel" match="brand"
use="concat(../@titel,'++',@titel)"/>
<xsl:template match="/*">
<xsl:apply-templates
select="type[count(.|key('kTypeByTitel',@titel)[1])=1]"/>
</xsl:template>
<xsl:template match="type">
<xsl:value-of select="@titel"/>
<xsl:apply-templates
select="key('kTypeByTitel',@titel)/brand[
count(.|key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)[1]
) = 1
]"/>
</xsl:template>
<xsl:template match="brand">
<xsl:if test="position()!=1">
<xsl:text>	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(',',@titel)"/>
<xsl:apply-templates select="key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)"
mode="color"/>
</xsl:template>
<xsl:template match="brand" mode="color">
<xsl:if test="position()!=1">
<xsl:text>	,	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(
',',
(color/@titel|color/text())[last()],
'
'
)"/>
</xsl:template>
</xsl:stylesheet>
Выход:
car,volvo,red
, ,green
,ford,red
bike,trek,blue
Примечание : Нет необходимости в заказном источнике входного сигнала.Исправлены поля, потому что общее решение (вложенная группировка по динамическим клавишам) было бы самой сложной задачей в XSLT 1.0