C# //<;节点>;不';不提供所有匹配的节点

C# //<;节点>;不';不提供所有匹配的节点,c#,xslt,C#,Xslt,给定以下XML: <root> <StepFusionSet name="SF1"> <StepFusionSet name="SF2"> </StepFusionSet> </StepFusionSet> <StepFusionSet name="SF10"> </StepFusionSet> </root> 给我输出: SF1 SF2 SF10 SF1

给定以下XML:

<root>
  <StepFusionSet name="SF1">
      <StepFusionSet name="SF2">
      </StepFusionSet>
  </StepFusionSet>
  <StepFusionSet name="SF10">
  </StepFusionSet>
</root>
给我输出:

SF1
SF2
SF10
SF1
SF10
但以下XSLT文件:

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="//StepFusionSet">
    <xsl:call-template name="a"/>
  </xsl:template>

  <xsl:template name="a">
      <xsl:apply-templates select="@name"/>
  </xsl:template>
</xsl:stylesheet>
给我输出:

SF1
SF2
SF10
SF1
SF10

我在XSLT文件中做错了什么?

考虑一下您的第一个模板

<xsl:template match="//StepFusionSet">
模板与外部
SF1
元素匹配;但是,为了匹配内部的
SF2
,它需要重新应用于匹配元素的子元素

这可以通过在第二个模板定义中嵌入递归的
来实现:

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="//StepFusionSet">
    <xsl:call-template name="a"/>
  </xsl:template>

  <xsl:template name="a">
    <xsl:apply-templates select="@name"/>
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

您的错误是假设由于match=“//StepFusion”模板匹配每个StepFusion元素,因此将调用它来处理每个StepFusion元素。事实上,它只处理xsl:apply-templates指令选择处理的StepFusion元素

我怀疑这种混淆经常存在于人们使用match'//stepfulsion“而不是更简单更清晰的match=“stepfulsion”的地方。match属性测试给定元素是否符合此模板规则的处理条件;是apply templates指令决定提交给此测试的元素

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="//StepFusionSet">
    <xsl:call-template name="a"/>
  </xsl:template>

  <xsl:template name="a">
    <xsl:apply-templates select="@name"/>
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <xsl:for-each select="//StepFusionSet">
      <xsl:value-of select="@name"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>