我有以下xml(实际上是FIX字典的非常简化的版本):
<fix>
<messages>
<message name='Message1'>
<field name='Field1' />
<component name='Component1'/>
<group name='Group1'>
<field name='Field2' />
</group>
</message>
</messages>
<components>
<component name='Component1'>
<field name='Field3' />
<group name='Group2' >
<field name='Field4' />
<group name='Group3' >
<field name='Field5' />
<component name='Component3' />
</group>
</group>
<component name='Component2' />
</component>
<component name='Component2'>
<field name='Field6' />
</component>
<component name='Component3'>
<field name='Field7'/>
</component>
</components>
<fields>
.....
</fields>
</fix>
每个消息,组件或组都可以具有字段,组件和组。
我需要计算每封邮件的组数。在上面的示例中,Message1的组数为3(Group1,Group2,Group3)
答案 0 :(得分:2)
我假设您要对引用的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上查看它的运行情况
实际上,这不会在component1和component2都引用了component3(其中包含组)中给出正确的结果,因为它将对同一组进行两次计数。
在这种情况下,请尝试使用此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>
如果component1引用了component2,但component2引用了component1,请警惕无限循环