Xml 使用XSLT计算嵌套子元素的数量

Xml 使用XSLT计算嵌套子元素的数量,xml,xslt,xpath,count,Xml,Xslt,Xpath,Count,我有以下xml(实际上是修复词典的一个非常简化的版本): ..... 每个消息、组件或组都可以有字段、组件和组 我需要计算每条消息的组数。在上面的示例中,Message1的组数为3(组1、组2、组3)我假设您要计算引用的组件元素中的组数,在第一条消息中引用的组件元素本身可以引用其他组件元素,这些元素中包含组 在这种情况下,递归函数就可以做到这一点 试试这个XSLT <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transfo

我有以下xml(实际上是修复词典的一个非常简化的版本):


.....
每个消息、组件或组都可以有字段、组件和组


我需要计算每条消息的组数。在上面的示例中,Message1的组数为3(组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="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>

看看它在哪里起作用

实际上,这不会在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,请小心无限循环。我假设您要计算引用的
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>

看看它在哪里起作用

实际上,这不会在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,那么要小心无限循环,您已经尝试了什么?为什么
Message1
的结果应该是
3
?它只包含1个
,而其他组是
组件的后代
您能否说您是否可以使用XSLT 2.0或更高版本,还是仅使用XSLT 1.0?@TimC我可以使用XSLT 2或更高版本,是的。@Andersson Message1在其对象图中有3个组。这些团体在哪里并不重要。这是我需要数一数的数字。稍后将发布我到目前为止尝试过的内容。谢谢@TimC,效果如预期。这个工具真的很有用!你已经试过什么了?为什么
Message1
的结果应该是
3
?它只包含1个
,而其他组是
组件的后代
您能否说您是否可以使用XSLT 2.0或更高版本,还是仅使用XSLT 1.0?@TimC我可以使用XSLT 2或更高版本,是的。@Andersson Message1在其对象图中有3个组。这些团体在哪里并不重要。这是我需要数一数的数字。稍后将发布我到目前为止尝试过的内容。谢谢@TimC,效果如预期。这个工具真的很有用!