Я предполагаю, что вы хотите сосчитать группы в элементах component
, на которые есть ссылки, и, кроме того, элементы component
, на которые есть ссылки в первом сообщении, сами могут ссылаться на другие элементы component
с группами в.
В этом случае рекурсивная функция сделает свое дело.
Попробуйте это XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:my="myFunctions">
<xsl:output method="text" />
<xsl:key name="components" match="components/component" use="@name" />
<xsl:template match="/">
<xsl:apply-templates select="//message[@name='Message1']" />
</xsl:template>
<xsl:template match="message">
<xsl:value-of select="my:groupCount(.)" />
</xsl:template>
<xsl:function name="my:groupCount">
<xsl:param name="node" />
<xsl:value-of select="count($node//group) + sum($node//component/my:groupCount(key('components', @name)))" />
</xsl:function>
</xsl:stylesheet>
См. Это в действии на http://xsltfiddle.liberty -development.net / jyH9rMP
На самом деле, это не даст правильных результатов в компоненте 1 и компоненте 2, на который ссылается компонент 3 (в котором были группы), поскольку он будет учитывать одну и ту же группу дважды.
В этом случае попробуйте этот XSLT вместо
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:my="myFunctions">
<xsl:output method="text" />
<xsl:key name="components" match="components/component" use="@name" />
<xsl:template match="/">
<xsl:apply-templates select="//message[@name='Message1']" />
</xsl:template>
<xsl:template match="message">
<xsl:value-of select="count(my:groups(.)/@name)" />
</xsl:template>
<xsl:function name="my:groups">
<xsl:param name="node" />
<xsl:sequence select="$node//group, $node//component/my:groups(key('components', @name))" />
</xsl:function>
</xsl:stylesheet>
Остерегайтесь бесконечных циклов, если компонент1 ссылается на компонент2, а компонент2 ссылается на компонент1